2011-11-03 95 views
2

我拿到这2个实体:JPA /休眠坚持级联即使它不应该

@javax.persistence.Entity 
public class Book { 
    @javax.persistence.EmbeddedId 
    private BookPK id; 

    private String title; 

    @javax.persistence.ManyToOne(fetch = javax.persistence.FetchType.LAZY) 
    @javax.persistence.JoinColumns({ 
      @javax.persistence.JoinColumn(name = "LNGCOD", referencedColumnName = "LNGCOD"), 
      @javax.persistence.JoinColumn(name = "LIBCOD", referencedColumnName = "LIBCOD") }) 
    private Language language; 
} 

@javax.persistence.Entity 
public class Language { 
    @javax.persistence.EmbeddedId 
    private LanguagePK id; 

    private String name; 
} 

与由PK的:

@Embeddable 
public class BookPK implements Serializable { 
    private Integer bookcod; 
    private Integer libcod; 
} 

@Embeddable 
public class LanguagePK implements Serializable { 
    private Integer lngcod; 
    private Integer libcod; 
} 

如果我尝试创建一个新的图书,并坚持它,我得到一个异常,告诉我libcod在insert语句中找到两次(“Column'libcod'指定两次”)。但是在定义JoinColumn时不能使用“insertable = false”(“在属性中不允许插入和不可插入的列混合”)。

有什么办法来定义这些对象+关系,所以列由Hibernate自动管理?

回答

2

当连接到会话时,Hibernate和JPA会自动对持久实体进行所有修改。这就是ORM的要点:你加载一个持久化对象,修改它,并且新的状态在事务提交时自动持久化,而不需要调用persist,merge,save或者其他方法。

请注意,在持久实体上调用persist(除了级联副作用)是没有意义的。 persist用于创建一个暂时的实体(即一个新的,不在数据库中,没有生成的ID)持久化。

+0

没关系。我匆匆做了测试,并犯了一些错误。测试应该与分离的对象一起运行。我现在遇到了一个新问题,请检查编辑后的问题。谢谢。 – ccc

+0

这里有一个非常奇怪的模式:在不改变主键的情况下改变图书的语言是不可能的。我会使用单列代理键。如果你不能,那么我会有两个独立的libcod列:一个用于本书的主键,另一个用于语言外键。 –

+0

问题是我无法更改数据库结构。我必须使用这个遗留数据库,所以我正试图找到通过JPA描述和管理它的最优雅方式。当然,我更喜欢有PK和FK的简单ID,但是... – ccc

0

您只能为libcod使用一个增变器。也许,你应该做的是将libcod getter留在BookPK类中,并且在Language类中,使用一个带有refc的连接列引用返回到libcod。它适用于单个嵌入式PK类,但对于多个PK类,您可能必须玩转。

所以,在你的语言课上,你会有这个。

@javax.persistence.Entity public class Language { 

    private LanguagePK id; 
    private Integer libcod; 

    @javax.persistence.EmbeddedId @AttributeOverrides({ 
     @AttributeOverride(name = "lngcod", column = @Column(name = "LNGCOD", nullable = false)), 
     @AttributeOverride(name = "libcod", column = @Column(name = "LIBCOD", nullable = false)) }) 
    public LanguagePK getId() { 
      return this.id; 
    } 
    public void setId(LanguagePK id) { 
      this.id = id; 
    }  


    @ManyToOne(fetch = FetchType.LAZY) 

     @JoinColumn(name = "LIBCOD", insertable = false , updatable = false) 
     public Integer getLibcod() { 
     return this.libcod; 
     }