3

有一个带有@OneToMany 映射到另一个实体(CoverArt)的实体类(Song),并将级联设置为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 注释不会导致更新封面艺术实体并且一切正常,只要我添加额外的逻辑来添加封面艺术,但我希望我不需要做这个。

4

2 回答 2

1

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

于 2012-03-08T11:04:15.283 回答
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 问候,马修

于 2015-05-14T13:47:51.517 回答