【问题标题】:JPA/Hibernate Persist cascades even if it shouldn'tJPA/Hibernate Persist 级联,即使它不应该
【发布时间】:2011-11-03 09:04:32
【问题描述】:

我得到了这两个实体:

@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(“列 'libcod' 指定了两次”)。但是在定义 JoinColumn 时不能使用“insertable = false”(“不允许在属性中混合可插入和不可插入的列”)。

有什么方法可以定义这些对象+关系,以便 Hibernate 自动管理这些列?

【问题讨论】:

    标签: java hibernate jpa persistence


    【解决方案1】:

    Hibernate 和 JPA 自动使对持久实体的所有修改在它们附加到会话时持久化。这就是 ORM 的全部意义:加载一个持久对象,对其进行修改,新状态会在事务提交时自动持久化,无需调用持久化、合并、保存或任何其他方法。

    请注意,在持久实体上调用 persist(除了其级联副作用)没有任何意义。 persist 是为了使一个临时实体(即一个新的,尚未在数据库中,没有生成的 ID)持久化。

    【讨论】:

    • 没关系。我匆忙设置测试并犯了一些错误。测试应该与分离的对象一起运行。我现在遇到了一个新问题,所以请检查已编辑的问题。谢谢。
    • 这里有一个非常奇怪的架构:如果不更改主键,就不可能更改一本书的语言。我会使用单列代理键。如果你不能,那么我将有两个单独的 libcod 列:一个用于书籍的主键,一个用于语言外键。
    • 问题是我无法更改数据库结构。我必须使用这个遗留数据库,所以我试图找到通过 JPA 描述和管理它的最优雅的方式。当然,我更喜欢 PK 和 FK 的简单 id,但是 ...
    【解决方案2】:

    对于 libcod,您只能拥有一个 mutator。可能,您应该做的是将 libcod getter 留在 BookPK 类中,并在 Language 类中,使用 joincolumn 引用和返回 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;
             }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 2011-11-23
      • 2014-11-16
      相关资源
      最近更新 更多