Spring 无法在Glassfish上保留任何带有EclipseLink的JPA实体
我想在Glassfish 3.1.2应用服务器上使用带有EclipseLink的JTA(容器管理事务)将JPA实体持久化到MySQL数据库。然而,这根本不起作用。EclipseLink日志显示正确执行了SELECT查询,并且还更新了序列。但是在调用Spring 无法在Glassfish上保留任何带有EclipseLink的JPA实体,spring,jpa,eclipselink,glassfish-3,jta,Spring,Jpa,Eclipselink,Glassfish 3,Jta,我想在Glassfish 3.1.2应用服务器上使用带有EclipseLink的JTA(容器管理事务)将JPA实体持久化到MySQL数据库。然而,这根本不起作用。EclipseLink日志显示正确执行了SELECT查询,并且还更新了序列。但是在调用persist()之后,不会执行插入查询 日食记录: persist() operation called on: my.package.name.MyEntity@d39a7b6. TX beginTransaction, status=NO_TRA
persist()
之后,不会执行插入查询
日食记录:
persist() operation called on: my.package.name.MyEntity@d39a7b6.
TX beginTransaction, status=NO_TRANSACTION
TX Internally starting
external transaction has begun internally
Connection acquired from connection pool [default].
Execute query DataModifyQuery(name="SEQUENCE" sql="UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + #PREALLOC_SIZE WHERE SEQ_NAME = #SEQ_NAME")
reconnecting to external connection pool
UPDATE SEQUENCE SET SEQ_COUNT = SEQ_COUNT + ? WHERE SEQ_NAME = ?
bind => [50, SEQ_GEN]|#]
Execute query ValueReadQuery(name="SEQUENCE" sql="SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = #SEQ_NAME")
SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
bind => [SEQ_GEN]
local sequencing preallocation for SEQ_GEN: objects: 50 , first: 14.501, last: 14.550
Connection released to connection pool [default].
TX commitTransaction, status=STATUS_ACTIVE
TX Internally committing
因此,我可以在MySQL数据库中看到序列更新,但是与MyEntity关联的表仍然是空的
这是我的实体类:
@Entity
@Table(name = "my_entity")
public class MyEntity implements Serializable, Cloneable {
@Id
@GeneratedValue
protected long id;
// (..) more fields
}
关于EntityManager,我正在使用基于Java的Spring配置,如下所示:
@Configuration
public class EntityManagerConfiguration {
@Bean
public EntityManagerFactory entities() throws Exception {
LocalContainerEntityManagerFactoryBean theEntityManager = new LocalContainerEntityManagerFactoryBean();
theEntityManager.setPackagesToScan(MyEntity.class.getPackage().getName());
theEntityManager.setJtaDataSource(dataSource());
theEntityManager.setPersistenceUnitName("entities");
theEntityManager.setJpaVendorAdapter(jpaVendorAdapter());
theEntityManager.setJpaProperties(jpaProperties());
theEntityManager.afterPropertiesSet();
return theEntityManager.getNativeEntityManagerFactory();
}
@Bean
public Properties jpaProperties() {
Properties props = new Properties();
props.setProperty("eclipselink.ddl-generation", "create-tables");
props.setProperty("eclipselink.weaving", "false");
props.setProperty("eclipselink.logging.level", "FINEST");
props.setProperty("eclipselink.logging.parameters", "true");
props.setProperty("eclipselink.target-server", "SunAS9");
return props;
}
@Bean
public DataSource dataSource() throws Exception {
return (DataSource) JNDIUtils.getLocalJNDIResource("jdbc/entitiesDB");
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter theVendorAdapter = new EclipseLinkJpaVendorAdapter();
theVendorAdapter.setDatabase(Database.MYSQL);
return theVendorAdapter;
}
@Bean
public PlatformTransactionManager platformTransactionManager(){
return new JtaTransactionManager();
}
}
请注意,persistence.xml
最后,调用persist()
方法的代码:
@Repository
public class EntityRepository {
@PersistenceContext(unitName = "entities")
private EntityManager entityManager;
public void persist(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}
我读过很多类似的问题,但没有一个能准确地反映我的问题,足以解决它。我遗漏了什么?嗯,我设法解决了。正如willome指出的,我需要在我的
persist()
方法上使用@Transactional
属性。此外,我需要将@EnableTransactionManagement
注释添加到我的EntityManager配置
类中。给了我这个主意
为了完成这个回答,我在下面列出了entitymanager配置
和EntityRepository
类的最终版本:
实体管理器配置
实体还原剂
现在我的实体很高兴地插入,我可以去庆祝周末了!(事实上,几小时后)在persist方法中添加@Transactional有什么效果吗?谢谢你的建议,willome。添加@Transactional不会改变任何事情。看起来em与事务的关联不正确。日志仅显示它获取持久化调用的序列值,但插入/更新在em关联到提交或刷新的事务被调用后进行。JTA是如何配置的,如果直接调用flush会发生什么?Chris,我使用注释配置配置了JTA,请参阅我提供的EntityManagerConfiguration类。我尝试在persist()调用的正下方添加entityManager.flush(),但这导致了TransactionRequiredException,并显示消息“此线程当前没有外部管理的事务处于活动状态”。这意味着您的提供程序的JTA配置未正确完成-entityManager未向JTA事务注册。您提到了glassfish,但这是Spring配置,您需要检查Spring配置。它没有将JPA EntityManager与用于事务的正确JTA事务管理器关联,或者缺少事务。如果在获得EM后启动了事务,请尝试调用EM.joinTransaction()。否则,希望其他人能帮忙,因为我不熟悉Spring。
@Configuration
@EnableTransactionManagement
public class EntityManagerConfiguration {
// class content did not change
}
@Repository
public class EntityRepository {
@PersistenceContext(unitName = "entities")
private EntityManager entityManager;
@Transactional
public void persist(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}