entityManager.persist没有将任何内容保存到数据库。

4
我使用的是Spring 4.2.5org.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>

我认为问题在于事务。但以下是调试日志。
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.这是什么问题?


有没有在某处吞掉了“TransactionRequiredException”异常? - Mena
你必须开始事务。通过调用entityManager.getTransaction().begin()。 要么使用EntityTransaction的commit方法,要么使用entityManager.flush();不要同时使用两者。 当你调用commit()时,事务将被关闭,你不能再次调用flush()。所以要明智选择。 - Atul Jain
4个回答

3
解决方案是注入EntityManager而不是EntityManagerFactory

为什么?我不得不做相反的事情;-) - jumping_monkey

1

提交(commit)会使数据库提交。对持久化对象的更改将被写入数据库。

当您拥有一个持久化对象并更改其值时,它会变为脏数据,Hibernate需要将这些更改刷新到您的持久化层。它可能会自动为您执行此操作,或者您可能需要手动执行此操作,这取决于您的刷新模式(自动或手动):)

最后,您应该使用commit:transaction.commit()确实会刷新会话(session),但它也结束了工作单元(unit of work)。

请查看此处获取更多信息。


2
如果我添加了 entityManager.flush(); 就会导致 javax.persistence.TransactionRequiredException: no transaction is in progress。这是什么问题? - TIMFUNNY
@TIMFUNNY 在你的类或方法中添加 @Transactional - Eboubaker

1

如果您正在使用

entityManager.persist(user);

执行此语句后,更改将不会反映在数据库中。 实体会自动将这些更改刷新到您的持久化层。 我们有手动刷新的选项。
entityManager.flush(); 

这应该可以解决您的问题。

2
如果我添加了 entityManager.flush(); 就会导致 javax.persistence.TransactionRequiredException: no transaction is in progress。这是什么问题? - TIMFUNNY
实体可以通过两种方式进行管理,一种是让容器自动管理,另一种是手动管理。在您的情况下,entityManager.getTransaction().begin()是手动处理的方法。如果您想让容器自动处理它,我们需要在web.xml中定义它。 - MyTwoCents

0

从下面的方法中删除EntityManagerFactory参数。相反,通过将其设置为JpaTransactionManager来注入您设置的那个。下面的代码将适用于您。

@Bean
public PlatformTransactionManager transactionManager(){
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(**entityManagerFactory().getObject()**);

    return transactionManager;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接