在Hibernate中使用CascadeType.ALL时保存顶级实体会导致对相关实体进行不必要的更新

时间:2012-02-28 22:43:16

标签: hibernate hibernate-envers hibernate-cascade

有一个实体类(Song),其中@OneToMany映射到另一个实体(CoverArt),并且级联设置为ALL,因为它似乎更容易保存主要内容并让它继续保持封面艺术< / p>

@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注释,修改一个字段不会导致封面艺术实体更新,一切正常,只要我添加额外的逻辑,当我添加封面艺术但我希望我没有需要这样做。

2 个答案:

答案 0 :(得分:1)

我好像修复了我使用反模式创建新会话然后每当我从数据库中检索任何内容时关闭它而不是将方法传递给现有会话并且只在我关闭会话后才解决问题完成了对象,修复这个已经解决了问题。

答案 1 :(得分:1)

我对自己的应用程序有确切的问题。 我有3个一对多的cascade = {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