【问题标题】:EntityManager persist() not saving anything to databaseEntityManager persist() 没有将任何内容保存到数据库
【发布时间】:2011-07-19 05:59:21
【问题描述】:

我的 entityManager persist() 从序列中获取 id 并将其放入我的 Image 对象中,但 Image 对象本身并未显示在数据库中。 EntityManager.flush() 给出一个错误,所以我不能以这种方式提交。这是我的代码。

@Repository
public class ImageDaoImpl extends BaseDao implements ImageDao {

@PersistenceContext
protected EntityManager entityManager;

@Override
@Transactional
public void create(Image image) {       
    JpaTemplate jpaTemplate = getJpaTemplate(entityManager);
    jpaTemplate.persist(image);
}

 

@Repository
public class BaseDao {

private JpaTemplate jpaTemplate;


public JpaTemplate getJpaTemplate(EntityManager entityManager){
    if(jpaTemplate == null)
        jpaTemplate = new JpaTemplate(entityManager);
    return jpaTemplate;
}

 

<bean id="entityManagerFactory"
       class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
       p:dataSource-ref="dataSource">
       <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
            </bean>
        </property>
        <property name="persistenceUnitName" value="sample"></property>
    </bean>



    <!-- DataSource Setup -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/imageCapture" />
        <property name="username" value="myusername" />
        <property name="password" value="mypassword" />
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

【问题讨论】:

标签: java hibernate spring jpa


【解决方案1】:

检查 EntityManager 对象没有被创建两次。在我的情况下,我在一个方法中初始化 EntityManager 对象,并在打开事务和持久化数据期间错误地调用了该方法两次。

不正确的代码:

EntityTrasaction transaction = getEntityManager().getTransaction().begin();
getEntityManager().persist(customer); // This line is calling another object of EntityManager
transaction.commit();

正确代码:

EntityManager em = getEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
em.persist(customer);
transaction.commit();

public EntityManager getEntityManager(){
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("punit");
    return entityManagerFactory.createEntityManager();
}

【讨论】:

    【解决方案2】:

    检查您的服务器日志。您是否正在创建新的EntityManger?并且还没有开始交易。我想,你开始的地方是另一个EntityManager 对象。

    【讨论】:

      【解决方案3】:

      我在使用SpringJUnit4ClassRunner 运行测试用例时遇到了这个问题

      我解决了 用

      包装测试函数
      @Autowired
      private PlatformTransactionManager transactionManager;
      
      // in your test funciton 
      // Declare a transaction programmatically to be able to rollback.
      DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
      transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
      TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
      
      try {
          // here test of Dao goes
      } finally {
          transactionManager.rollback(transaction);
      }
      

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        persist() 表示“将对象添加到托管条目列表”。要将对象保存到数据库,您必须调用flush() 方法。但请记住,您必须在事务内部调用。

        //编辑: 示例保存方法。

        public void save(T t){
            // begin transaction 
            em.getTransaction().begin();
            if (!em.contains(t)) {
                // persist object - add to entity manager
                em.persist(t);
                // flush em - save to DB
                em.flush();
            }
            // commit transaction at all
            em.getTransaction().commit();
        }
        

        这不是你能做到的最好的,但已经足够了。

        【讨论】:

        • flush() 在提交之前被调用。
        • 添加 entityManager.flush() 并得到 javax.persistence.TransactionRequiredException: no transaction is in progress
        • 还有一个。 JpaTemplate 只是 javax.persistance.EntityManager 的门面。
        • 我也有同样的问题。但我的是容器管理的 entitymanager,所以我无法调用getTransaction() 方法。我该如何解决?
        • To save object to data base you must call flush() method. - 不是真的......我猜最好说“你必须承诺”。
        【解决方案5】:

        检查您的 mvc-dispatcher-servlet.xml 。 &lt;context:component-scan base-package="pass"/&gt; 中的 pass 应该等于你的控制器所在的包

        【讨论】:

          【解决方案6】:

          这通常发生在未应用事务时。我怀疑@Transactional 拦截器没有正确拦截。

          【讨论】:

          • 还有一件事要检查:请确保,@Transactional 注释来自包 org.springframework.transaction.annotation,而不是 javax.transaction - 第二个在我的情况下不起作用。
          • @Gondy 你先生,刚刚结束了我长达 2 小时的痛苦。非常感谢!
          • @Gondy Spring 还添加了对 javax.transaction.Transactional 的支持,现在人们也可以在 Spring 应用程序中使用它。只是不要将两者混为一谈,并且要始终如一地选择!
          猜你喜欢
          • 2011-09-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-11
          • 1970-01-01
          • 1970-01-01
          • 2021-11-09
          • 1970-01-01
          相关资源
          最近更新 更多