2017-02-20 15 views
3

私は、Hibernateでのフラッシュに関して異なる動作を示す2つのメソッドを持っています。Hibernate AUTOフラッシュ戦略の注文

@Transactional 
    public void firstMthod(int id, int status) { 
     Person entity = session.get(Person.class, id); 
     entity .setStatus(personStatus.registered); 
     session.merge(entity); 
     updatePersonAge(id,18); 
    } 

updatePersonAgeメソッドが別のクラスに位置しており、この方法のSQL出力は次のようになります:

最初のものである

select personel0_.ID   as ID1_119_0_, 
     personel0_.status  as status2_119_0_, 
     personel0_.age   as age3_119_0_, 
     personel0_.CreatedBy  as CreatedBy4_119_0_, 
     personel0_.UpdatedBy  as UpdatedBy5_119_0_, 
     personel0_.CreatedDate as CreatedDate6_119_0_, 
     personel0_.UpdatedDate as UpdatedDate7_119_0_, 
     personel0_.Ip   as Ip8_119_0_ 
    from tbl_personel personel0_ 
where personel0_.ID = ? 
update tbl_person set status = ? where ID = ? 
update tbl_person set age = ? where ID = ? 

および第2の使用ケースのために、我々は以下の方法を有する。

@Override 
    @Transactional 
    public void secondMethod(int id,int courseId, int status) { 
     Course courseEntity=session.get(Course .class, courseId); 
     courseEntity.setCreatedDate(new Date()); 
     session.merge(courseEntity); 
     updatePersonAge(id,18); 
    } 

updatePersonAge m ethodは、以下のSQL出力を生成する:

select course0_.ID   as ID1_120_0_, 
     course0_.CreatedBy as CreatedBy7_120_0_, 
     course0_.UpdatedBy as UpdatedBy8_120_0_, 
     course0_.CreatedDate as CreatedDate9_120_0_, 
     course0_.UpdatedDate as UpdatedDate10_120_0_, 
     course0_.Ip   as Ip11_120_0_ 
    from tbl_course course0_ 
where course0_.ID = ? 
update tbl_course set created_date = ? where ID = ? 
update tbl_person set age = ? where ID = ? 

updatePersoneAge方法がある:

public int updatePersonAge(int id,int age){ 
     Query query = session.createQuery("update " + domainClass.getName() + " e set e.age= :age "); 
       query.setParameter("age ", age); 
       return query.executeUpdate(); 
     } 

私の予想によれば、第2の方法の出力は、第1の方法の出力と同じでなければなりません。だから違いは何ですか?それは本当に混乱しています。

+0

"update"コマンドのような更新クエリを取得したブロックトランザクションでは、その行の前に実行されますが、なぜ2番目のメソッドの結果がわからないのかわかりません。 –

答えて

0

updatePersonAgeメソッドの中で、年齢を明示的に更新することは別として、エンティティを取得してフィールドの1つを変更することによって、管理対象エンティティの他のフィールドも暗黙的に更新します。

これらの変更をマージすると、PErsistence Providerはトランザクションの終了時にこれらの変更をフラッシュする義務を負います。

Person entity = session.get(Person.class, id); 
     entity .setStatus(personStatus.registered); 
     session.merge(entity); 

Hibernateは、明示的な年齢upateと一緒にその変更を永続化:第2の方法では

update tbl_person set status = ? where ID = ? 
update tbl_person set age = ? where ID = ? 

を使用すると、コースのエンティティのフィールドを変更したときにステータスを変更したときに、なぜ

ザッツ:

Course courseEntity=session.get(Course .class, courseId); 
     courseEntity.setCreatedDate(new Date()); 
     session.merge(courseEntity); 

この変更は、明示的な年齢制限upda TE:すべての

update tbl_course set created_date = ? where ID = ? 
update tbl_person set age = ? where ID = ? 
2

まず、それはすでに現在実行中のSessionに装着されたエンティティにmergeを呼び出すことも意味がありません。 Mergeは、when you want to attach a detached entityを使用することを意味します。

this articleで説明したように、Hibernate AUTO flushは、実行しようとしているクエリがActionQueueのエンティティと重複している場合にのみフラッシュをトリガーします。

最初の例では、Personを変更したため、クエリはPersonに対して実行されていたため、フラッシュをトリガーすると意味があります。そうでない場合、SQLクエリは古い結果を返す可能性があります。

Courseエンティティを変更しても、Personから選択したい場合は、次のように入力します。したがって、フラッシュをトリガする必要はありません。

Query.addSyncronizedEntityNameを使用してこの動作を制御できます(this articleで説明)。