2013-04-02 17 views
1

有了以下的裝飾和條件,@OneToOne需要CascadeType.MERGE嗎?

/** 
* passsalt. 
*/ 
@JoinColumn(name = "PASSSALT_ID", nullable = false) 
@OneToOne(cascade = {CascadeType.PERSIST, 
        CascadeType.MERGE, // is this actually required? 
        CascadeType.REMOVE}, 
      optional = false, orphanRemoval = true) 
@NotNull 
@XmlTransient 
private Morton passsalt; 
  • passsalt必須用這個實體persited一起。 (CascadeType.PERSIST
  • passsalt可以替換爲新的detached實例。 (CascadeType.MERGE?)
  • passsalt刪除此實體時必須刪除。 (CascadeType.REMOVE
  • Morton沒有字段更新

一個疑問:CascadeType.MERGE是強制性的?

我使用和不使用CascadeType.MERGE進行了測試,看起來沒有它。

問題2:問題標題中的「是」是否正確?它應該是「是」嗎?

這裏是替換passsalt的方法。

public boolean nassword(final Shadow reference, final byte[] password, 
         final byte[] nassword) { 

    passsalt = new Morton(); 
    passcode = passsalt.salty(nassword); 

    return true; 
} 

我用以下方法測試。

@Test(enabled = true, invocationCount = 1) 
public void testNassword0() { 
    final EntityManager manager = LocalPU.createEntityManager(); 
    try { 
     final EntityTransaction transaction = manager.getTransaction(); 
     transaction.begin(); 
     try { 
      final String username = newUsername(manager); 
      final byte[] password = newPassword(); 
      Shadow shadow = persistInstance(manager, username, password); 
      Assert.assertTrue(shadow.puthenticate(shadow, password)); 
      System.out.println("========================================="); 
      LOGGER.log(Level.INFO, "mortons: {0}", 
         MORTONS(manager, 0, 1024)); 
      final byte[] nassword = newPassword(); 
      shadow.nassword(shadow, password, nassword); 
      shadow = manager.merge(shadow); 
      manager.flush(); 
      System.out.println("========================================="); 
      LOGGER.log(Level.INFO, "mortons: {0}", 
         MORTONS(manager, 0, 1024)); 
      Assert.assertFalse(shadow.puthenticate(shadow, password)); 
      Assert.assertTrue(shadow.puthenticate(shadow, nassword)); 
      transaction.commit(); 
     } catch (Exception e) { 
      transaction.rollback(); 
      e.printStackTrace(System.err); 
      Assert.fail(e.getMessage()); 
     } 
    } finally { 
     manager.close(); 
    } 
} 

這是輸出。

4월 02, 2013 11:55:03 오전 org.hibernate.validator.internal.util.Version <clinit> 
INFO: HV000001: Hibernate Validator 4.3.0.Final 
[EL Info]: 2013-04-02 11:55:03.897--ServerSession(571229670)--EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461 
[EL Info]: 2013-04-02 11:55:04.744--ServerSession(571229670)--file:/E:/svnwc/jinahya.googlecode.com/trunk/com.googlecode.jinahya/jinahya-ee/target/test-classes/_localPU login successful 
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Morton _PrePersist 
INFO: _PrePersist(): [email protected]&id=1048576 
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: puthenticate([email protected]?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[[email protected], [[email protected]) 
4월 02, 2013 11:55:06 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: passsalt: [email protected]&id=1048576 
========================================= 
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.ShadowTest testNassword0 
INFO: mortons: [[email protected]&id=1048576] 
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow nassword 
INFO: nassword([email protected]?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[[email protected], [[email protected], [[email protected]) 
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: puthenticate([email protected]?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[[email protected], [[email protected]) 
4월 02, 2013 11:55:08 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: passsalt: [email protected]&id=1048576 
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Morton _PrePersist 
INFO: _PrePersist(): [email protected]&id=1048577 
========================================= 
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.ShadowTest testNassword0 
INFO: mortons: [[email protected]&id=1048577] 
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: puthenticate([email protected]?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[[email protected], [[email protected]) 
4월 02, 2013 11:55:11 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: passsalt: [email protected]&id=1048577 
4월 02, 2013 11:55:12 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: puthenticate([email protected]?id=1048576&username=0KIWHFirmA581Qf5AscsrVbN9YW30pAF&passcode=[[email protected], [[email protected]) 
4월 02, 2013 11:55:12 오전 com.googlecode.jinahya.persistence.Shadow puthenticate 
INFO: passsalt: [email protected]&id=1048577 

綜上所述,

After persisted ->   mortons: [[email protected]&id=1048576] 
After replaced and merged -> mortons: [[email protected]&id=1048577] 
+0

您是否使用分離的對象進行測試?那實際上包含了一個「Morton」的實例? – Perception

+0

是的,我相信。我更新了這個問題。 –

回答

3

簡短的回答,它不是必需的。

級聯堅持和合並是獨立的事情。當您調用persistence在所屬實體上時,使用Cascade Persist,從而導致持續在所引用的passsalt上調用。如果級聯持續存在於關係中,則暗示當調用flush或commit時也會引用新對象。

另一方面,合併適用於合併操作。當你在實體上調用合併時,它會導致合併也在passsalt上被調用。如果它存在並且只是被分離,那麼變化將被拾取。如果它是新的,它將被插入,類似於如果持續被調用。未指定級聯合並時會發生什麼情況,並且該關係引用分離的對象由規範覆蓋,但對於實體是新的會發生什麼情況似乎灰色。它指出返回的擁有實體引用了一個passsalt的託管實例,這意味着它將被插入,因爲託管實例需要在刷新或提交時與數據庫同步。所以它應該沒有任何作用,但取決於你如何使用合併api以及你的JPA提供者的行爲方式,你可能想保持它的設置。沒有它意味着改變現有passsalt(如果你不只是取代它當然)不會被拿起。

此外,您正在使用orphanRemoval,因此級聯刪除是隱含的,不需要。 OrphanRemoval意味着如果沒有所有者實體,引用的passsalt就不能存在,所以當所有者被刪除或取消引用passsalt時,它將從數據庫中刪除,而不需要級聯刪除設置。