gpt4 book ai didi

java - JPA:外部容器事务未提交

转载 作者:行者123 更新时间:2023-11-30 10:52:09 25 4
gpt4 key购买 nike

我正在为我的应用程序测试 JPA。

与数据库的连接似乎成功了,

Running com.vgorcinschi.rimmanew.ejbs.OutsideContainerJpaTests 
[EL Info]: 2015-12-25 07:32:26.202--ServerSession(1302779492)--EclipseLink, version: Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd
[EL Info]: connection: 2015-12-25 07:32:26.493--ServerSession(1302779492)--file:/home/vgorcinschi/NetBeansProjects/RimmaNew/target/classes/_outsideContainer login successful

但是数据没有持久化。

因为我的应用程序在 GlassFish 上运行并且我在容器外尝试 JUnit 测试,所以我创建了第二个持久性单元。这是 persistence.xml 文件中的内容(请注意,我已将我的凭据隐藏到数据库中):

<persistence-unit name="outsideContainer" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://127.0.0.1:3306/beaty_shop?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="**********"/>
<property name="javax.persistence.jdbc.password" value="*************"/>
</properties>
</persistence-unit>

这是返回 EntityManagerFactory 的单例方法:

public static EntityManagerFactory getUniqueInstance() {
if (uniqueInstance == null) {
synchronized (EntityManagerFactoryProvider.class) {
if (uniqueInstance == null) {
uniqueInstance = Persistence.createEntityManagerFactory("outsideContainer");
}
}
}
return uniqueInstance;
}

这是存储库 stub ,它不会抛出异常,但也不会将数据持久保存到数据库中。事务已启动并提交...

public class JpaAppointmentRepositoryStub implements AppointmentRepository {



private EntityManagerFactory emf;

public JpaAppointmentRepositoryStub(EntityManagerFactory emf) {
this.emf = emf;
}

public JpaAppointmentRepositoryStub() {
}

@Override
public void add(Appointment appointment) {
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction trans = em.getTransaction();
try {
trans.begin();
em.persist(appointment);
trans.commit();
} catch (Exception e) {
trans.rollback();
} finally {
em.close();
}
}

@Override
public void update(Appointment appointment) {
EntityManager em = entityManagerFactory.createEntityManager();
em.merge(appointment);
}

@Override
public Appointment get(long id) {
EntityManager em = entityManagerFactory.createEntityManager();
try {
return em.find(Appointment.class, id);
} catch (NoResultException e) {
return null;
} finally {
em.close();
}
}


}

来自 EntityManager 的事务不为空:

@Test
public void aTransactionIsNotNull(){
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction trans = em.getTransaction();
assertNotNull(trans);
em.close();
}

最后一条有趣且有用的信息是 Repository 正由一个服务类“操作”,该服务类具有用于 Repository 的保存和更新操作的单一方法。所以唯一的缺点应该是在每次调用时打开和关闭两个实体管理器:

public class OutsideContainerAppointmentService implements AppointmentService{
private final AppointmentRepository repository;
...
@Override
public void save(Appointment appointment) {
if (findById(appointment.getId()) != null)
repository.update(appointment);
else
repository.add(appointment);
}
...
}

MySQL Connector/J 在此 Maven 项目的测试依赖项中(但由于登录成功,这不是问题)。

那么您认为可能是什么问题?

最佳答案

尽管这没有意义(至少到目前为止),正确的解决方案是这样。

我添加了 .joinTransaction() 方法,一切开始正常工作。

    @Override
public void add(Appointment appointment) {
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction trans = em.getTransaction();
trans.begin();
try {
//this is the line that I have added
em.joinTransaction();
em.persist(appointment);
trans.commit();
} catch (Exception e) {
trans.rollback();
} finally {
em.close();
}
}

但根据JPA wiki在这种情况下我不应该使用 .joinTransaction() :

joinTransaction is only used with JTA managed EntityManagers (JTA transaction-type in persistence.xml). For RESOURCE_LOCAL EntityManagers you can just commit the JPA transaction whenever you desire.

我必须修复的另一个“错误”是将 appointmentService.save(dummy); 转移到 setUp() 方法外部和 @Test 注释方法内部。这就是我开始对数据库进行双重写入的原因。

关于java - JPA:外部容器事务未提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34463244/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com