2012-03-09 5 views
2

| AA |多対多| BB |多対多| CC | AA_BB | | - | - | BB | - | BB_CC | - | CC | AA |にマッピングされ再度JoinTableは多対多休止状態の関係で埋められません

はテーブルが

になった参加します

(私は画像申し訳ありませんが、低い評判を投稿することはできません)

編集: 短い質問は、Bbの要素をAaの要素を作成した場合、Ccの要素 はAaのにBbのコレクション、BbのにCcとを追加する理由 ですコレクション 保存(Aa) 作業OK(AA_BB塗りつぶし)?

しかし、私はBbの要素、Aaの要素を作成する場合は、Ccの要素 はBbのコレクション にAaの追加BbのコレクションにCcを追加 保存(BB) (AA_BB ないが満たされた?)

BB_CCは常にありますいっぱい。

エンド編集

CREATE TABLE BB_CC (
    BBIDBB number(10) NOT NULL, 
    CCIDCC number(10) NOT NULL, 
    PRIMARY KEY (BBIDBB, 
    CCIDCC)); 
CREATE TABLE AA_BB (
    AAIDAA number(10) NOT NULL, 
    BBIDBB number(10) NOT NULL, 
    PRIMARY KEY (AAIDAA, 
    BBIDBB)); 
CREATE TABLE CC (
    IDCC number(10) NOT NULL, 
    DESCR varchar2(10) NOT NULL, 
    PRIMARY KEY (IDCC)); 
CREATE TABLE BB (
    IDBB number(10) NOT NULL, 
    DESCR varchar2(10) NOT NULL, 
    PRIMARY KEY (IDBB)); 
CREATE TABLE AA (
    IDAA number(10) NOT NULL, 
    DESCR varchar2(10) NOT NULL, 
    PRIMARY KEY (IDAA)); 
ALTER TABLE BB_CC ADD CONSTRAINT FKBB_CC976918 FOREIGN KEY (BBIDBB) REFERENCES BB (IDBB); 
ALTER TABLE BB_CC ADD CONSTRAINT FKBB_CC529716 FOREIGN KEY (CCIDCC) REFERENCES CC (IDCC); 
ALTER TABLE AA_BB ADD CONSTRAINT FKAA_BB470776 FOREIGN KEY (AAIDAA) REFERENCES AA (IDAA); 
ALTER TABLE AA_BB ADD CONSTRAINT FKAA_BB23574 FOREIGN KEY (BBIDBB) REFERENCES BB (IDBB); 

Hibernate構成

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
<!-- ORACLE --> 
     <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
     <property name="connection.url">jdbc:oracle:thin:@10.10.1.8:1521:GEROS</property> 
     <property name="connection.username">xxxx</property> 
     <property name="connection.password">xxxx</property> 
     <property name="dialect">org.hibernate.dialect.OracleDialect</property> 

     <!-- JDBC connection pool (use the built-in) --> 
     <property name="connection.pool_size">1</property> 

     <!-- Disable the second-level cache --> 
     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 

     <!-- Echo all executed SQL to stdout --> 
     <property name="show_sql">true</property> 

     <!-- Drop and re-create the database schema on startup--> 
     <property name="hbm2ddl.auto">create</property> 

     <!-- Names the annotated entity class --> 
     <mapping class="it.erreeffe.erreeffe2.Aa"/> 
     <mapping class="it.erreeffe.erreeffe2.Bb"/> 
     <mapping class="it.erreeffe.erreeffe2.Cc"/> 
    </session-factory> 
</hibernate-configuration> 

をファイルとテーブル AA(同様のBB、CC)欠落しているいくつかの部分から逆にJPAクラス。

@Entity 
public class Aa implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @SequenceGenerator(name="AA_IDAA_GENERATOR", sequenceName="SEQ_AA") 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AA_IDAA_GENERATOR") 
    private long idaa; 

    private String descr; 

    //bi-directional many-to-many association to Bb 
    @ManyToMany(cascade={CascadeType.ALL}) 
    @JoinTable(
     name="AA_BB" 
     , joinColumns={ 
      @JoinColumn(name="AAIDAA") 
      } 
     , inverseJoinColumns={ 
      @JoinColumn(name="BBIDBB") 
      } 
     ) 
    private Set<Bb> bbs; 

私のテストは、最初の作業と2番目のテストではありません。

まず:

Session session; 
     SessionFactory sf_ORA = new Configuration().configure(
       "hibernate.cfg.ora.xml").buildSessionFactory(); 
     session = sf_ORA.openSession(); 

//A 
     Aa a = new Aa(); 
     a.setDescr("A1"); 
     a.setBbs(new HashSet<Bb>()); 
     //B 
     Bb b1 = new Bb(); 
     b1.setCcs(new HashSet<Cc>()); 
     Bb b2 =new Bb(); 
     b2.setCcs(new HashSet<Cc>()); 
     b1.setDescr("B1"); 
     b2.setDescr("B2"); 
     //C 
     Cc c1 = new Cc(); 
     Cc c2 = new Cc(); 
     Cc c3 = new Cc(); 
     c1.setDescr("C1"); 
     c2.setDescr("C2"); 
     c3.setDescr("C3"); 
     //FILL B 
     b1.getCcs().add(c1); 
     b1.getCcs().add(c2); 
     b2.getCcs().add(c2); 
     b2.getCcs().add(c3); 
     //FILL A 
     a.getBbs().add(b1); 
     a.getBbs().add(b2); 

session.beginTransaction(); 
     try 
     { 
      session.save(a); 
      session.flush(); 
      session.getTransaction().commit(); 
     } 
     catch(HibernateException ex) 
     { 
      session.getTransaction().rollback(); 
      throw ex; 
     } 

この右の仕事をする: Hibernateは私のために必要なすべての書類を作成します。

Hibernate: insert into Aa (descr, idaa) values (?, ?) 
Hibernate: insert into Bb (descr, idbb) values (?, ?) 
Hibernate: insert into Cc (descr, idcc) values (?, ?) 
Hibernate: insert into Cc (descr, idcc) values (?, ?) 
Hibernate: insert into Bb (descr, idbb) values (?, ?) 
Hibernate: insert into Cc (descr, idcc) values (?, ?) 
Hibernate: insert into AA_BB (AAIDAA, BBIDBB) values (?, ?) 
Hibernate: insert into AA_BB (AAIDAA, BBIDBB) values (?, ?) 
Hibernate: insert into BB_CC (BBIDBB, CCIDCC) values (?, ?) 
Hibernate: insert into BB_CC (BBIDBB, CCIDCC) values (?, ?) 
Hibernate: insert into BB_CC (BBIDBB, CCIDCC) values (?, ?) 
Hibernate: insert into BB_CC (BBIDBB, CCIDCC) values (?, ?) 

入社結果クエリは右である:

A1 | B1 | C1

A1 | B1 | C2

A1 | B2 | C2

A1 | B2 | C3

セカンド(TA-ダンここでそれが問題である)DBから 読み取りB1追加B1.Aasコレクションに新しいAA(A2)を追加新しいCc(c4)をB1.Ccsコレクションに更新し、B1を更新します。

Bb b1=null; 
     session.beginTransaction(); 
     try 
     { 
      Query qGetB1=session.createQuery("Select id from Bb where DESCR ='B1'"); 
      long idB1=(Long) qGetB1.list().get(0); 
      b1=(Bb) session.load(Bb.class, idB1); 
      session.flush(); 
      session.getTransaction().commit(); 
     } 
     catch(HibernateException ex) 
     { 
      session.getTransaction().rollback(); 
      throw ex; 
     } 

     Aa a2 = new Aa(); 
     a2.setDescr("A2"); 
     Cc c4 = new Cc(); 
     c4.setDescr("C4"); 

     b1.getAas().add(a2); 
     b1.getCcs().add(c4); 


     session.beginTransaction(); 
     try 
     { 
      session.flush(); 
      session.saveOrUpdate(b1); 
      session.flush(); 
      session.getTransaction().commit(); 
     } 
     catch(HibernateException ex) 
     { 
      session.getTransaction().rollback(); 
      throw ex; 
     } 

Hibernateの生成:

Hibernate: select bb0_.idbb as col_0_0_ from Bb bb0_ where DESCR='B1' //SEARCH B1 ID 
Hibernate: select bb0_.idbb as idbb1_0_, bb0_.descr as descr1_0_ from Bb bb0_ where bb0_.idbb=? //GET B1 
Hibernate: select aas0_.BBIDBB as BBIDBB1_1_, aas0_.AAIDAA as AAIDAA1_, aa1_.idaa as idaa0_0_, aa1_.descr as descr0_0_ from AA_BB aas0_, Aa aa1_ where aas0_.AAIDAA=aa1_.idaa and aas0_.BBIDBB=? GET B1.Aas 
Hibernate: select ccs0_.BBIDBB as BBIDBB1_1_, ccs0_.CCIDCC as CCIDCC1_, cc1_.idcc as idcc2_0_, cc1_.descr as descr2_0_ from BB_CC ccs0_, Cc cc1_ where ccs0_.CCIDCC=cc1_.idcc and ccs0_.BBIDBB=? GET B1.Ccs 
Hibernate: insert into Aa (descr, idaa) values (?, ?) //OK 
Hibernate: insert into Cc (descr, idcc) values (?, ?) //OK 
Hibernate: insert into BB_CC (BBIDBB, CCIDCC) values (?, ?) //OK 


... What about AA_BB record???? //!!!!!!!! 

joinTable AA_BBが満たされていないのはなぜ?

ありがとうございます。 よろしく、 Francesco。

答えて

6

双方向の関連付けがある場合、一方の側はオーナー側(mappedBy属性のない側)で、もう一方は逆側(mappedBy属性を持つ側)です。

Hibernateは、所有者側が2つのエンティティ間に関連があるかどうかを知ることのみを考慮します。したがって、AがAとBの間の関係のオーナー側である場合、AのコレクションにBインスタンスを追加して、関連を永続化する必要があります。インスタンスをBのコレクションに追加しても効果はありません。一般的に

あなたがは、オブジェクトグラフの一貫性を維持する責任があるので、あなたは所有者側が(少なくとも)は常に更新されていることを確認する必要があります。

+0

これは答えです。本当にありがとう。 –

+0

誰かが文書に記載されている場所を知っていますか? – ds011591

+1

JPA仕様の第3.2.4項「管理対象エンティティ間の双方向関係は、関係の所有側が保有する参照に基づいて維持されます。所有側でメモリ内参照を保持するのは開発者の責任です。彼らが変わったときに相互に一貫性のある逆の側で保持される[...]関係の逆側への変更が所有側で適切な更新をもたらすことを確実にすることが特に重要である。それらがデータベースに同期されると失われます。 –

関連する問題