2011-04-27 51 views

回答

36

您可以通過致電Session.evict()來分離實體。

其他選項是在轉換值之前創建實體的防禦副本,或者在代碼中使用DTO而不是實體。我認爲這些選項更優雅,因爲它們不轉換到JSON和持久層。

+9

對於JPA,您可以使用: ['EntityManager.detach(object)'](http://docs.oracle.com/javaee/7/api/javax/persistence/E ntityManager.html#detach%28java.lang.Object%29) – 2014-01-13 13:48:39

+1

我總是使用DTO來達到這個目的。使用防禦副本是個好主意,但是今年的維護變得更加困難,人們認爲新的對象是一個託管的對象,但實際上它實際上是一個本地副本。 – VimalKumar 2015-07-29 19:47:13

+0

EntityManager.detach(變量)也適用於我 – kiedysktos 2017-01-27 14:23:06

0

關閉會話。這會讓你的實體分離,並且不會進行修改。如果這是不可能的,查看禁用autoFlush ...但這是一個其他的蠕蟲。最簡單的就是關閉會議並完成它!

3

我也在將Hibernate實體轉換爲JSON。

當你關閉會話時你不能延遲加載對象的壞處。因此,您可以使用

hSession.setDefaultReadOnly(true); 

並在您完成JSON後關閉會話。

3

您還可以避免通過使用您的實體連接到Hibernate會話StatelessSession:的

StatelessSession session = sessionFactory.openStatelessSession(); 

代替

Session session = sessionFactory.getCurrentSession(); 

請注意,你必須要小心關閉StatelessSession的自己,不像常規休眠會話:

session.close(); // do this after you are done with the session 

與常規會話相比的另一個區別是StatelessSession無法提取集合。我看到它的主要目的是獲取數據,只有SQLQuery的東西。

您可以在此處詳細瞭解不同的會話類型:

http://www.interviewadda.com/difference-between-getcurrentsession-opensession-and-openstatelesssession/

0
public static <E> E deepClone(E e) { 
    ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
    ObjectOutputStream oo; 
    try { 
     oo = new ObjectOutputStream(bo); 
     oo.writeObject(e); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
    ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); 
    ObjectInputStream oi; 
    try { 
     oi = new ObjectInputStream(bi); 
     return (E) (oi.readObject()); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
     return null; 
    } catch (ClassNotFoundException ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
} 

第一:deepClone會議POJO
第二:改變場
然後:做任何你想做的事情

相關問題