0

継承テーブルの 2 つのセットがあります: 1. TableA (TableA1 と TableA2 によって継承)、2. TableB (TableB1 と TableB2 によって継承)

TableA の DiscriminatorColumn は 'type' で、DiscriminatorValues は TableA1 と TableA2 のそれぞれ 'A1' と 'A2' です。同様に、TableB の DiscriminatorColumn は「type」で、DiscriminatorValues は TableB1 と TableB2 のそれぞれ「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;
    }
4

1 に答える 1

0

あなたが説明したことから、TableA1 と TableB1 の間に ManyToMany 関連付けがあり、TableA2 と TableB2 の間に別の ManyToMany 関連付けが必要です。ただし、これら 2 つの関連付けを、TableA と TableB の間の単一の関連付けとしてマップしました。これら 2 つの関連付けを実際のものとしてマッピングする必要があります。

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

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

同じ結合テーブルを使用して 2 つの異なる関連付けをマップすることはありません。それが可能かどうかさえわかりません。

于 2013-01-01T09:17:16.133 に答える