无法在Glassfish上使用EclipseLink保留任何JPA实体

时间:2014-01-23 10:56:48

标签: spring jpa eclipselink glassfish-3 jta

我想在Glassfish 3.1.2应用服务器上使用带有EclipseLink的JTA(容器管理事务)将JPA实体持久化到MySQL数据库。但是,这根本不起作用。 EclipseLink日志显示SELECT查询正确执行,并且序列也更新。但是在调用persist()后没有执行INSERT查询。

EclipseLink日志记录:

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
    }

我正在使用基于Java的Spring Configuration关于EntityManager,如下所示:

@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 is not needed any more when using the setPackagesToScan() method

最后,调用persist()方法的代码:

@Repository
public class EntityRepository {

    @PersistenceContext(unitName = "entities")
    private EntityManager entityManager;

    public void persist(MyEntity myEntity) {
        entityManager.persist(myEntity);
    }
}

我在SO上已经阅读了很多类似的问题,但是它们似乎都没有足够精确地反映我的问题以便能够解决它。我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

好吧,我设法解决了这个问题。正如遗嘱指出的那样,我需要在@Transactional方法上使用persist()属性。此外,我需要将@EnableTransactionManagement注释添加到我的EntityManagerConfiguration类。 This Spring blog给了我这个主意。

要完成此回答,我列出了以下EntityManagerConfigurationEntityRepository类的最终版本:

EntityManagerConfiguration

@Configuration
@EnableTransactionManagement
public class EntityManagerConfiguration {

   // class content did not change

}

EntityRepository

@Repository
public class EntityRepository {

    @PersistenceContext(unitName = "entities")
    private EntityManager entityManager;

    @Transactional
    public void persist(MyEntity myEntity) {
        entityManager.persist(myEntity);
    }
}

现在我的实体很乐意插入,我可以去周末庆祝! (好吧,事实上几个小时)