2013-10-23 91 views
0

当我使用GenerationType.IDENTITY或GenerationType.AUTO为我的表ID,我坚持一个事务内的实体,数据瞬间插入,并在事务结束之前! !JPA 2 /休眠/ MySql GenerationType.AUTO

我试图改变whit GenerationType.TABLE,生成并执行我的MYSQL数据库中的新关联的DDL,现在它正在工作。 有人可以解释我为什么吗?

提取物:

@Table 
@Entity 
public class Foo implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "id", nullable = false, unique = true) 
    private Long id; 

     ... 
} 


@Repository 
public class EntityDaoServiceImpl { 

    @PersistenceContext 
    protected EntityManager em; 

     @Transactional 
    public void testFooCreation() { 
      Foo foo = new Foo(); 
      em.persit(foo); 
      //at this point with the AUTO or IDENTITY strategie, 
      //i ve got an effective insert in base otherwise with the TABLE strategie, 
      //the insert is effective at the end of my transaction (the excepted behavior) 
    } 

} 
+0

'我有一个有效的插入基地'你如何检查? (在'em.persist();'后面添加一个伪'System.out.println(“Breakpoint”);'在那里放置一个断点,并用外部工具查看你的表Foo,看看新行是) – ben75

回答

0

它将按预期工作,因为没有一个人说,直到交易没有完成,插入未在DB做。这个想法是,JPA提供者(Hibernate在你的情况下)决定什么时候对数据库进行刷新,看起来在GenerationType.TABLE的情况下,它决定在早期进行。但是,因为该刷新已完成,所以这并不意味着该事务已完成/已提交:在保留您/或JPA提供程序可以回滚该事务之后,该行不会保留在数据库中。 PS:我希望你有一些关于事务(google用于事务隔离级别)和/或MySql的存储引擎(InnoDB是事务引擎,而MyIsam不是)的背景知识。

+0

我使用InnoDB作为事务引擎,但是使用GenerateType.AUTO,在持久化之后,行被插入,im始终在事务中如果我杀了我的进程,该行仍然在dataBase中,我没有任何回滚。 –

+0

您是否在尝试持久化实体后抛出RuntimeException,而不是查杀该进程?您是否尝试过观看Hibernate的日志,以查看事务是否开始/如何回滚/提交? –

+0

非常感谢所有这些精度Andrei和Ben75,对于我来说,我对持久化上下文中的数据感到困惑,并且将数据从persitence上下文冲刷到数据库,但是现在可以了。所以我把目光移开了,我已经得到了答案!我正在使用InnoDb方言hibernate.dialect属性,但我的表是创建了没有ENGINE = InnoDB !!!!!!!! –