[英]Spring3 JPA (Hibernate4) not persisting
我有一个使用Spring 3.2.3和Hibernate 4.2.1.Final的应用程序。 我做了一些配置,应用程序在测试环境中运行得非常好,使用HSQLDB等。
但是当部署应用程序时,它几乎可以正常工作。 实体已创建但从未保留。 我可以看到JPA日志:
Hibernate:选择nextval('TASK_SEQ')
但是插件永远不会出现=(
使用配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<context:component-scan base-package="br.com.company" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="spring_pu" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
persistence.xml中
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="spring_pu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>br.com.company.core.entities.Task</class>
<properties>
<property name="hibernate.connection.autocommit" value="true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.url" value="jdbc:postgresql://127.0.0.1:5432/companyDB" />
<property name="hibernate.connection.user" value="postgres" />
<property name="hibernate.connection.password" value="*****" />
</properties>
</persistence-unit>
</persistence>
实体:
@Entity
@Table(name = "TASK")
public class Task implements Serializable {
private static final long serialVersionUID = -6262731134419520342L;
@Id
@Column(name = "ID")
@GeneratedValue(generator = "TASK_SEQ", strategy = GenerationType.SEQUENCE)
@SequenceGenerator(sequenceName = "TASK_SEQ", name = "TASK_SEQ")
private long id;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "FINISHED")
private boolean fininshed;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "FINISH_DATE")
private Date finishDate;
//getters and setter below
}
最后服务:
@Service
public class TaskService {
@PersistenceContext
private EntityManager entityManager;
@Transactional(propagation = Propagation.REQUIRED)
public void createTask(Task task) {
<b>//invoked method</b>
entityManager.persist(task);
}
正如我所说,没有异常被抛出,但实体并没有像测试那样持久存在。 谢谢!
编辑:我还尝试将persistence.xml内容删除到spring数据源中,问题仍然是相同的:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://127.0.0.1:5432/KCILDS" />
<property name="username" value="postgres" />
<property name="password" value="*****" />
</bean>
<context:component-scan base-package="br.com.company" />
<bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="br.com.company.core.entities" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEntityManagerFactory" />
</bean>
<context:annotation-config />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
解:
我放弃了xml配置。 似乎没有任何东西可以用它了。 阅读更多有关趋势和大量配置的信息,我最终成功尝试了java配置并进行了一些调整,这非常适合。 见下文:
@Configuration
@EnableTransactionManagement
@ComponentScan("br.com.company")
public class PersistenceJPAConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(this.directDataSource());
factoryBean.setPackagesToScan(new String[] { "br.com.company" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setShowSql(true);
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setJpaProperties(this.additionlProperties());
return factoryBean;
}
private Properties additionlProperties() {
Properties properties = new Properties();
properties.put("database", "POSTGRESQL");
properties.put("databasePlatform", "org.hibernate.dialect.PostgreSQLDialect");
properties.put(Environment.SHOW_SQL, true);
properties.put(Environment.FORMAT_SQL, true);
return properties;
}
// now reasearch how to make it an environment configuration
// @Bean
// public DataSource dataSource() {
// JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
// jndiDataSourceLookup.setResourceRef(true);
// return jndiDataSourceLookup.getDataSource("jdbc/mybank");
// }
@Bean
public DataSource directDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://127.0.0.1:5432/MyBank");
dataSource.setUsername("postgres");
dataSource.setPassword("*******");
return dataSource;
}
@Bean //still trying to make a JTA Transaction
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(this.entityManagerFactoryBean().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
首先,您应该启用PersistenceAnnotationBeanPostProcessor
bean,如下所示:
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
如Spring 3.1.x doc,第14.5.2节中所述 :
如果启用了PersistenceAnnotationBeanPostProcessor,Spring可以在字段和方法级别理解@PersistenceUnit和@PersistenceContext注释。
另一件事,确保您的TaskService
被扫描。 根据发布的Spring配置文件,只扫描包br.com.company
,因此TaskService
应位于该包下。
编辑
您应该将@Transactional
用于实现interface
public
方法。 默认情况下,Spring通过简单的Java Proxy
实现通知注释,这需要一个接口。
Spring AOP默认使用AOP代理的标准J2SE动态代理。 这使得任何接口(或接口集)都可以被代理。
当然,这也意味着TaskService
应该仅通过该接口由其他bean引用。
我遇到了类似于描述的问题。 我发现@Transactional表示法的使用不正确的问题,特别是我错误地使用了javax.transaction.Transactional而不是org.springframework.transaction.annotation.Transactional
看一下“@Service”的导入。
有关差异的详细说明,请参见javax.transaction.Transactional vs org.springframework.transaction.annotation.Transactional
由于TaskService
被定义为服务,因此Spring容器不会维护CRUD操作的事务。 您应该将CRUD操作委托给另一个bean - 通常我将它们与Managers后缀。
这将是事务工作流的完整层次结构:
TaskManager
@Resource(name =“taskManager”)
TaskManager taskManager;
3。 在新创建的Manager类中注入EntityManager
等
4。 将所有CRUD方法放在manager类中
5。 从Service调用这些方法
呼叫层次结构:服务 - >管理器 - > DAO - >实体管理器
现在你应该能够坚持你的实体了。
我首先要仔细检查一些明显的东西:Task类型是br.com.company.Task,而不是其他java api任务?
如果您仍然遇到同样的问题,那么您的交易管理可能出现问题。 保持后尝试刷新entityManager。 通常,entityManager应在事务结束时自动刷新:
@Transactional(propagation = Propagation.REQUIRED)
public void createTask(Task task) {
entityManager.persist(task);
entityManager.flush(task);
}
如果您确实遇到了事务管理器的问题,请尝试而不是在persistence.xml中指定数据源,在spring xml上创建它并使用JpaTransactionManager的dataSource属性
还可以在log4j logger之后设置以查看hibernate发出的事务开始/结束和SQL:
log4j.logger.org.hibernate.SQL=DEBUG
log4j.logger.org.hibernate.transaction=DEBUG
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.