【问题标题】:Mapping a class that consists only of a composite PK without @IdClass or @EmbeddedId映射仅由没有 @IdClass 或 @EmbeddedId 的复合 PK 组成的类
【发布时间】:2011-10-17 11:36:40
【问题描述】:

我有两个表 AB 带有简单的 PK。

@Entity
public class A { 
    @Id
    public int idA;
}

@Entity
public class B { 
    @Id
    public int idB;
}

我想映射一个新的关联类 AB,它只存储 AB 之间的关系,组合 PK idA+idBAB 没有任何额外的列,只有idAidB 之间的关系。

是否可以使用单个类映射AB?我想避免创建一个新的ABId 类只是为了将其用作AB 中的@IdClass@EmbeddedId,并且我不想将它与@ManyToMany 上的@ManyToMany 关联映射或B

【问题讨论】:

    标签: java hibernate hibernate-mapping hibernate-annotations


    【解决方案1】:

    为什么要映射这样的连接表?只需在 A 和 B 之间使用 ManyToMany 关联。当您向 A 中包含的 B 列表添加/删除 B 时,将自动处理此连接表。

    http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#d0e11402

    如果您真的想这样做,那么只需将两个 ID 与 @Id 表示法进行映射。主类将是实体类本身(必须是可序列化的),如hibernate reference documentation 中所述。请注意,这是特定于 Hibernate 的。

    【讨论】:

    • 我想这样做是因为我已经映射了 AB,它们是不太可能改变的静态数据(以及许多其他此类未映射的关系)。 AB 也是如此。我有一个在启动时检索到的idA 列表存储在一个spring bean 中,我想在启动时构建一个 Map> 。当恢复A 的列表时,该表将避免在启动时与AB 进行连接或子查询。我可能最终不会使用 Hibernate 映射它并使用本机 SQL 查询它。
    • 太好了,这正是我所需要的。我不认为它适用于hibernate-annotations 3.3.1.GA,但根据HHH-4327
    • 不出所料,我刚刚测试了这个,session.createCriteria(AB.class).list() 的 SQL 查询休眠抛出是这样的:select this_.ID_A as COD2_248_0_ from AB this_。所有idB 字段均为空。我会尝试更新到最新版本。
    • 在与hibernate-core 3.6.7.Final 的测试中,这按预期工作。但是,我没有升级。我会坚持使用带有内部静态类的@IdClass。
    【解决方案2】:

    如果@JBNizet 的suggestion 有效,那就太好了。不幸的是,有一个old bug,这使得我无法在我正在使用的版本(3.3.1-GA)中采用它

    我终于通过定义一个内部静态 ID 类并将其用作@IdClass 来解决这个问题:

    @Entity
    @Table(name="TABLE_AB")
    @IdClass(value=ClassAB.ClassABId.class)
    public class ClassAB implements Serializable {
    
        private String idA;
        private String idB;
    
        @Id
        public String getIdA(){ return idA; }
        public void setIdA(String idA){ this.idA = idA; }
    
        @Id
        public String getIdB(){ return idB; }
        public void setIdB(String idB){ this.idB = idB; }
    
        static class ClassABId implements Serializable {
            private String idA;
            private String idB;
    
            @Column(name="ID_A")
            public String getIdA(){ return idA; }
            public void setIdA(String idA){ this.idA = idA; }
    
            @Column(name="ID_B")
            public String getIdB(){ return idB; }
            public void setIdB(String idB){ this.idB = idB; }
    
            // HashCode(), equals()
        }
    }
    

    这样我不必定义新的公共类,也不必修改映射文件以包含 ID 类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 2016-12-01
      相关资源
      最近更新 更多