EJB,JPA/Hibernate。我无法在数据库中插入

EJB, JPA/Hibernate. I cannot make an insert in a database

我使用 Glassfish、EJB、JPA 和 Hibernate 作为 JPA 实现。我可以通过 JPA 从数据库中获取 select,但插入不起作用。看起来像 JTA 的问题(可能是事务未完成或我使用了另一个事务)持久性内容不会刷新到数据库。当我使用 eclipselink 作为 JPA 实现时,相同的代码可以正常工作,但我必须使用 hibernate。



    @Stateless
    @LocalBean
    public class BeanISManagedByContainer
    {

        @PersistenceContext(unitName = "com.company_JPATest2-ejb_ejb_1.0PU")
        EntityManager entityManager;

        public String getMessage(int id)
        {
            return entityManager.find(Message.class, id).getText();
        }

        public void addMessaage(String txt)
        {
            Message message = new Message();
            message.setText(txt);
            entityManager.persist(message);
        }
    }


getMessage() 方法工作正常,但 addMessaage() 没有向数据库插入任何数据,也没有任何日志。持久性上下文未刷新到数据库。我曾尝试手动管理交易,但结果相同。我不知道休眠配置有什么问题。请指教



    @Stateless
    @LocalBean
    @TransactionManagement(TransactionManagementType.BEAN)
    public class ManualTransactions
    {
        @PersistenceContext(unitName = "com.company_JPATest2-ejb_ejb_1.0PU")
        EntityManager entityManager;

        @Resource
        private UserTransaction transaction;

        public void addMessaage(String txt) throws Exception
        {
            Message message = new Message();
            message.setText(txt);

            transaction.begin();
            Logger.getLogger(ManualTransactions.class.getName())
                    .info("transaction status: " + transaction.getStatus());
            entityManager.persist(message);
            Logger.getLogger(ManualTransactions.class.getName())
                    .info("transaction status: " + transaction.getStatus());
            transaction.commit();
            Logger.getLogger(ManualTransactions.class.getName())
                    .info("transaction status: " + transaction.getStatus());
        }
    }

**logs:**
Info:   transaction status: 0
Info:   transaction status: 0
Info:   transaction status: 6


persistance.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="com.company_JPATest2-ejb_ejb_1.0PU" transaction-type="JTA">
 <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
 <jta-data-source>jdbc/JPATestPool</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
  <property name="hibernate.show_sql" value="true"/>
  <property name="hibernate.format_sql" value="true"/>
  <property name="hibernate.use_sql_comments" value="true"/>
 </properties>
  </persistence-unit>
</persistence>

pow.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <artifactId>JPATest2</artifactId>
    <groupId>com.company</groupId>
    <version>1.0</version>
  </parent>

    <groupId>com.company</groupId>
    <artifactId>JPATest2-ejb</artifactId>
    <version>1.0</version>
    <packaging>ejb</packaging>

    <name>JPATest2-ejb</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.2.12.Final</version>
  </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <ejbVersion>3.1</ejbVersion>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

JPA EntityManager 需要与容器 JTA 平台交互以获得回调,以便刷新上下文。根据 JPA 引擎,它可能会或可能不会检测到容器的 JTA TransactionManager。

对于 Hibernate,您需要通过提供一个 属性 来协助它,该 属性 提供用于检测 JTA 基础结构的实现。

将以下 属性 添加到 persistence.xml

的属性部分
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />

org.hibernate.service.jta.platform.internal.SunOneJtaPlatform 特定于 Glassfish。您必须相应地更改以匹配您正在使用的应用程序服务器

在容器管理的事务场景下,需要在希望提交事务的方法中添加@Transactional。

    @Transactional
    public void addMessaage(String txt)
    {
        Message message = new Message();
        message.setText(txt);
        entityManager.persist(message);
    }