【问题标题】:EJB, JPA/Hibernate. I cannot make an insert in a databaseEJB、JPA/休眠。我无法在数据库中插入
【发布时间】:2018-07-18 04:06:03
【问题描述】:

我使用 Glassfish、EJB、JPA 和 Hibernate 作为 JPA 实现。我可以通过 JPA 从数据库中获取选择,但插入不起作用。看起来 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>

【问题讨论】:

    标签: java hibernate jpa ejb


    【解决方案1】:

    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。您必须进行相应更改以匹配您正在使用的应用程序服务器

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-27
        • 2015-07-27
        • 1970-01-01
        • 1970-01-01
        • 2017-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多