拥有一个实体类(Song),该实体类具有到另一个实体(CoverArt)的@OneToMany映射,并级联设置为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;
....
}
但我后来在代码中发现,如果我只是从数据库中检索该类的一个实例,然后在会话中只修改了Song实体中的一个字段,这将导致它更新链接到该歌曲的所有封面艺术实体,即使封面艺术没有任何更改,它为什么要这样做?
此外,我不认为这会导致问题,但我正在使用Envers,对CoverArt表的(似乎)不必要的额外更新也会导致Envers创建不必要的审计表。
如果我删除了CascadeType注释,修改一个字段不会导致封面艺术实体被更新,只要我添加了添加封面艺术时的额外逻辑,一切都可以,但我希望我不需要这样做。
我似乎已经解决了我使用的反模式的问题,即创建一个新的会话,然后每当我从DB中检索到任何东西时都关闭它,而不是向方法传递一个现有的会话,只有在我完成对象后才关闭会话,解决了这个问题。
我自己的应用程序确实有问题。我有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;
}
联系人genest@gmail.com问候,Mathieu