2017-03-19 14 views
7

新しいコードにマップしようとしている従来のコードがあります。複雑な結合のためのHibernateマッピング

OLD_PERSON 
pid 
sid 
name 
age 

NEW_PERSON 
pid 
sid 
fid 
age 

RESOLVE_PERSON 
pid 
fid 
status 

レガシーの世界では

domain.Person { 
ID _id; 
String _name; 
Integer _age; 
} 

Javaクラスは、ただ一つのテーブルがありました:OLD_TABLE。ハイバネーションマッピングはシンプルで、1つのクラスとその列だけでした。新しい世界では、上記の3つのテーブルを使用して、名前がOLD_PERSONからNEW_PERSONになる1つのエンティティを生成する必要があります。だから、基本的にSQLクエリは次のとおりです。

select op.name as name, np.age as age 
from OLD_PERSON op 
INNER JOIN RESOLVE_PERSON rp 
on rp.pid = op.pid 
INNER JOIN NEW_PERSON np 
on np.pid = rp.pid and np.fid = rp.fid and np.sid = op.sid 
where rp.status = 'CURRENT' 

研究の際に/私は休止XMLで「JOINテーブル」に相当している「セカンダリ表」を使用することができることを見出したグーグル。 注:このコードは古く、私はまだhibernate3.5.6ですので、注釈を使用することはできません。

は、だから、私は、マッピングファイル内の結合テーブルを追加しました:

<class name="domain.Person" table="OLD_PERSON"> 
     <composite-id name="_id" class="Id"> 
      <key-property access="property" name="key1" type="long" column="pid" /> 
      <key-property access="property" name="key2" type="int" column="sid" /> 

      <generator class="assigned" /> 
     </composite-id> 

     <property name="_Name" type="String" column="name" /> 

     <join table="NEW_PERSON" fetch="join" inverse="false"> 
      <key> 
      <column name="pid" /> 
      <column name="sid" /> 
      </key> 
      <property name="_age" column="age" not-null="true" /> 
     </join> 
</class> 

をしかしNEW_PERSONテーブルに内部結合がRESOLVE_PERSONテーブルと結合が必要です。私はsubselectを使ってみましたが、正しいものではありません。私はここにの式を差し込めません。

どのようにこれを達成することができるでしょうか?私が基本的に求めているのは、JOINの基準/制約チェックを適用する方法です。

答えて

1

私はあなたの問題と同様の状況でした。私はエンティティに3番目のテーブルをマッピングして、このエンティティのDAOを使用して、そのプロパティによって何かを取得します。ここで

は、

DAOは非常に正常である(私は、アノテーションを使用しているので、これはあなたが直接使用することができますが、うまくいけば、それはあなたにいくつかのインスピレーションを与えるものではありませんので)、コードで

@Entity 
@Table(name = "resolve_person") 
public class ResolvePerson implements java.io.Serializable { 
    private OldPerson old; 
    private NewPerson new; 

    ... 

    @ManyToOne // you may change it to other relationships 
    @JoinColumn(name = "pid", nullable = false) 
    public OldPerson getOldPerson() { 
     return this.old; 
    } 

    public void setOldPerson (OldPerson old) { 
     this.old = old; 
    } 

    @Id 
    @GeneratedValue(generator = "idGenerator") 
    @GenericGenerator(name = "idGenerator", strategy = "foreign", 
      parameters = { @org.hibernate.annotations.Parameter(name = "property", value = "fid") }) 
    @Column(name = "fid", nullable = false, unique = true) 
    public NewPerson getNewPerson() { 
     return this.New; 
    } 

    public void setNewPerson (NewPerson new) { 
     this.new = new; 
    } 
} 

public List findByProperty(String propertyName, Object value) { 
     log.debug("finding ResolvePerson instance with property: " 
       + propertyName + ", value: " + value); 
     try { 
      String queryString = "from ResolvePerson as model where model." 
        + propertyName + "= ?"; 
      Query queryObject = getSession().createQuery(queryString); 
      queryObject.setParameter(0, value); 
      return queryObject.list(); 
     } catch (RuntimeException re) { 
      log.error("find by property name failed", re); 
      throw re; 
     } 
    } 

プロパティ "status"を "current"に設定してクエリできます。

関連する問題