【问题标题】:Hibernate : Jointable to join a particular child tableHibernate:可连接以加入特定的子表
【发布时间】:2012-12-15 23:59:43
【问题描述】:

我有两组继承表: 1. TableA(由TableA1和TableA2继承), 2. TableB(由TableB1和TableB2继承)

TableA 的 DiscriminatorColumn 是“type”,TableA1 和 TableA2 的 DiscriminatorValues 分别是“A1”和“A2”。 同样,TableB 的 DiscriminatorColumn 是“type”,TableB1 和 TableB2 的 DiscriminatorValues 分别是“B1”和“B2”。 我有一个用于连接 TableA 和 TableB 的连接表 TableA_B。我知道连接表 TableA_B 只能将 TableA1 链接到 TableB1,而 TableA2 只能链接到 TableB2,这根据“类型”列发生。即,A1 总是链接到 B1 类型,A2 总是链接到 B2 类型。

现在,我的问题是,当我从 TableA1 进行查询时,@JoinTable 会生成连接 TableA1、TableA、TableB、TableB1 和 TableB2 的 sql。在这里,不需要从 TableB2 进行查询。有没有办法限制这个?正如我所提到的,唯一的区别因素是“类型”列。

TableA 实体:

@Entity
@Table(name = "TableA")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="type")
public class TableA {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(unique = true, nullable = false)
    private Long id;
    private String name;
    private String type;

    @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(
        name="TableA_B",
        joinColumns={@JoinColumn(name="A_id")},
        inverseJoinColumns={@JoinColumn(name="B_id")}
        )
    private Set<DataMaster> inputData = new HashSet<DataMaster>(0);


//getters & setters ...
}

@Entity
@Table(name = "TableA1")
@PrimaryKeyJoinColumn(name="AId")
@DiscriminatorValue("A1")
public class TableA1 extends TableA{

    @Column(insertable=false, updatable=false)
    private Long AId;
    private String value1;
//getters & setters ...
}

@Entity
@Table(name = "TableA2")
@PrimaryKeyJoinColumn(name="AId")
@DiscriminatorValue("A2")
public class TableA2 extends TableA{

    @Column(insertable=false, updatable=false)
    private Long AId;
    private String value2;
//getters & setters ...
}

TableB如下:

@Entity
@Table(name = "TableB")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="type")
public class TableB {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(unique = true, nullable = false)
    private Long id;
    private String name;
    private String type;
//getters & setters ...
}

@Entity
@Table(name = "TableB1")
@PrimaryKeyJoinColumn(name="BId")
@DiscriminatorValue("B1")
public class TableB1 extends TableB{
    @Column(insertable=false, updatable=false)
    private Long dataId;
    private String value1;
//getters & setters ...
}

@Entity
@Table(name = "TableB2")
@PrimaryKeyJoinColumn(name="BId")
@DiscriminatorValue("B2")
public class TableB2 extends TableB{
    @Column(insertable=false, updatable=false)
    private Long dataId;
    private String value2;
//getters & setters ...
}

道:

public TableA1 find(Long id) {
      Session session = DBSessionManager.getFactory().openSession();
      Transaction tx = null;
      TableA1 tableA1 = null;
      try{
         tx = session.beginTransaction();
         tableA1 = (TableA1)session.get(TableA1.class, id);
         tx.commit();
      }catch (HibernateException e) {
         if (tx!=null) tx.rollback();
      }finally {
         session.close(); 
      }     
      return tableA1;
}

我尝试使用 FilterJoinTable 作为:

@FilterJoinTable(name="dataTypeFilter", condition=":dataType = type")

在 DAO 中,

session.enableFilter("dataTypeFilter").setParameter("dataType", "B1");

但是,这也没有给出预期的结果。

这就是我添加过滤器的方式:

@Entity
@Table(name = "TableA")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="type")
@FilterDef(name="dataTypeFilter", parameters = {
        @ParamDef(name = "dataType", type = "string")
        })
public class TableA {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(unique = true, nullable = false)
    private Long id;
    private String name;
    private String type;

    @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(
        name="TableA_B",
        joinColumns={@JoinColumn(name="A_id")},
        inverseJoinColumns={@JoinColumn(name="B_id")}
        )
    @FilterJoinTable(name="dataTypeFilter", condition=":dataType = type")
    private Set<DataMaster> inputData = new HashSet<DataMaster>(0);


//getters & setters ...
}

道:

public TableA1 find(Long id) {
          Session session = DBSessionManager.getFactory().openSession();
          Transaction tx = null;
          TableA1 tableA1 = null;
          try{
             tx = session.beginTransaction();
         session.enableFilter("dataTypeFilter").setParameter("dataType", "B1");
             tableA1 = (TableA1)session.get(TableA1.class, id);
             tx.commit();
          }catch (HibernateException e) {
             if (tx!=null) tx.rollback();
          }finally {
             session.close(); 
          }     
          return tableA1;
    }

【问题讨论】:

  • 您能否发布带有@FilterDef@FilterJoinTable 的代码 - 如果没有看到@FilterDef,很难确切知道发生了什么
  • 我已经用过滤器代码更新了问题。谢谢。

标签: java hibernate hibernate-mapping jointable


【解决方案1】:

根据您的描述,TableA1 和 TableB1 之间应该有一个 ManyToMany 关联,TableA2 和 TableB2 之间应该有另一个 ManyToMany 关联。但是您将这两个关联映射为 TableA 和 TableB 之间的单个关联。您应该将这两个关联映射为真实的:

private class TableA1 extends TableA {
    @ManyToMany
    private Set<TableB1> tablesB1s;
}

private class TableA2 extends TableA {
    @ManyToMany
    private Set<TableB2> tablesB2s;
}

我不会使用同一个连接表来映射两个不同的关联。我什至不确定这是否可能。

【讨论】:

    猜你喜欢
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 2022-12-14
    相关资源
    最近更新 更多