2012-02-28 78 views
2

將實體類(Song)與@OneToMany映射到另一個實體(CoverArt)並級聯設置爲ALL,因爲看起來更容易保存主entiy讓它來堅持封面在休眠時使用CascadeType.ALL保存頂級實體會導致對相關實體的不必要更新

@Audited 
@Entity 
public class Song 
{ 
    @Id 
    @GeneratedValue 
    private Integer recNo; 

    @Version 
    private int version; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    private List<CoverArt> coverArts; 

    .... 

} 

的照顧,而且我發現在代碼稍後,如果我只是檢索和數據庫中的類的實例,然後會在短短修改歌曲實體中的一個字段會導致它更新與該歌曲鏈接的所有封面藝術實體,即使封面藝術沒有任何改變,爲什麼它會這樣做?

此外,我不認爲它會導致問題,但我正在使用Envers,並且對CoverArt表的(看似)不必要的額外更新具有造成Envers創建不必要的審計表的敲擊作用。

如果我刪除CascadeType註釋修改一個字段不會導致封面藝術實體更新,並且一切正常,只要我添加額外的邏輯,當我添加封面藝術,但我希望我沒有'不需要這樣做。

+0

你以某種方式改變coverArts收集的實例?可能是因爲休眠失去了更改跟蹤。另外,如果CoverArt對Song有反向引用,最好在@OneToMany上反轉= true。 – Firo 2012-02-29 13:02:40

+0

這是什麼意思,我沒有對coverart做任何修改。它沒有反向引用, – 2012-02-29 14:28:15

+0

Hibernate以某種方式認爲CoverArts已經改變。如果Hibernate設置爲字段的集合被交換,或者如果所有屬性的值都不相等,因爲它們以某種方式更改,那麼引用父對象。爲CoverArt設置dynamicupdate = true以查看哪些字段實際上正在更改。 – Firo 2012-02-29 15:26:53

回答

1

我似乎已經解決了我使用創建新會話的反模式的問題,然後在我從數據庫中檢索任何內容時關閉它,而不是將方法傳遞給現有會話,只關閉會話,已經完成了對象,解決這個問題已經解決了。

1

我有我自己的應用程序的確切問題。 我有3個一對多的級聯= {CascadeType.ALL}

有人可以給我一個例子,適當的會話重用工作。 我的代碼:

public class HibernateUtil { 

private static final SessionFactory sessionFactory = buildSessionFactory(); 

private static SessionFactory buildSessionFactory() { 
    try { 
     // Create the SessionFactory from hibernate.cfg.xml 
     Configuration conf = new Configuration().configure(); 
     ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); 
     SessionFactory sf = conf.buildSessionFactory(sr); 
     return sf; 
    } 
    catch (HibernateException ex) { 
     // Make sure you log the exception, as it might be swallowed 
     System.err.println("Initial SessionFactory creation failed." + ex); 
     throw new ExceptionInInitializerError(ex); 
    } 
} 

public static SessionFactory getSessionFactory() { 
    return sessionFactory; 
} 

} 


public groupelti.lims.persistence.vo.LotEchantillonRegulier modifier(groupelti.lims.persistence.vo.LotEchantillonRegulier ler) throws DAOException { 

    // validation 
    if (ler == null) { 
     throw new IllegalArgumentException(); 
    } 
    if (ler.getId() == null) { 
     throw new IllegalArgumentException(); 
    } 
    if (ler.getId() <= 0) { 
     throw new IllegalArgumentException(); 
    } 

    // traitement 
    Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
    session.beginTransaction(); 

    try { 
     session.update(ler); 
     session.getTransaction().commit(); 
    } catch (PropertyValueException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (ConstraintViolationException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (GenericJDBCException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (TransientObjectException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } finally { 
     try { 
      session.close(); 
     } catch (SessionException e) { 
      //do nothing 
     } 
    } 

    return ler; 
} 

接觸[email protected] 問候,馬蒂厄