2012-02-28 31 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] 问候,马蒂厄