我使用Spring 4.2.5
和org.hibernate 5.1.0
。
当我使用entityManager.persist(user)
保存user
时,它无法保存到数据库,也没有错误抛出。
但如果我添加entityManager.getTransaction().begin();
和entityManager.getTransaction().commit();
,那就有效了。
下面的代码
@Service
@Transactional
public class UserTestService {
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
public void addUser(User user){
EntityManager entityManager = entityManagerFactory.createEntityManager();
//entityManager.getTransaction().begin();
entityManager.persist(user);
//entityManager.getTransaction().commit();
}
}
我的配置
@Configuration
@EnableTransactionManagement
public class JPAConfig {
@Autowired
private DataSource dataSource;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter() );
entityManagerFactoryBean.setPackagesToScan("zhihu.model");
return entityManagerFactoryBean;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setShowSql(true);
adapter.setGenerateDdl(false);
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
return adapter;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}
我的模特
@Entity
@Table(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long userID;
@Column(name="username")
private String username;
@Column(name="password")
private String password;
public User(){
}
public User(long userID, String username, String password) {
this.userID = userID;
this.username = username;
this.password = password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public long getUserID() {
return userID;
}
public void setUserID(long userID) {
this.userID = userID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
的pom.xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
</dependencies>
我认为问题是Transactional
。但是下面的调试日志。
2016-05-05 21:33:10 DEBUG TransactionImpl:51 - begin
2016-05-05 21:33:10 DEBUG TransactionImpl:62 - committing
更新
如果我添加entityManager.flush();
导致javax.persistence.TransactionRequiredException: no transaction is in progress.
有什么问题?
答案 0 :(得分:1)
解决方案是注入EntityManager
而不是EntityManagerFactory
答案 1 :(得分:0)
提交将使数据库提交。对持久对象的更改将写入数据库。
当你有一个持久化对象而你在其上更改一个值时,它就会变脏,而hibernate需要将这些更改刷新到你的持久层。它可能会自动为您执行此操作,或者您可能需要手动执行此操作,具体取决于您的刷新模式(自动或手动):)
最后你应该使用commit:transaction.commit()会刷新会话,但它也会结束工作单元。
查看here了解更多信息。
答案 2 :(得分:0)
如果您正在使用
entityManager.persist(user);
执行此语句后,更改将不会反映在数据库中。 实体管理自动将这些更改刷新到您的持久层。
我们可以选择使用
手动清除它entityManager.flush();
这应该可以解决您的问题