Hibernate错误地将实体视为不可变的

时间:2019-01-23 10:14:04

标签: java spring hibernate

我们在应用程序中使用的是Hibernate 3.3.2 / Spring 3.0.5,其中一个服务器模块仍然使用旧的HibernateTemplate / HibernateDaoSupport类。 我一直试图删除这些,因为我必须在此模块中实现我们自己的事务逻辑。 问题是,如果我直接访问会话而不是使用HibernateTemplate,则Hibernate的行为就像所有实体都带有@Immutable注释:我可以创建新的数据库条目并删除这些或旧的数据库条目,但是我无法再更新现有的条目

我将问题缩小到DefaultFlushEventListener.onFlush,在这种情况下,source.getPersistenceContext().hasNonReadOnlyEntities()总是返回false,但是我仍然找不到为什么此标志设置错误的原因。 我还验证了没有一个实体真正被注释为@Immutable,也没有使用Query.setReadOnlySession.setReadOnly主动设置为只读。

更糟糕的是,将readonly=false设置在任何地方也无效,该实体保持不变。

在其他服务器模块中,我们从未使用过HibernateTemplate / HibernateDaoSupport,并且这些功能在所有CRUD操作中都能正常工作。

这是使用旧的Hibernate类的代码:

@Transactional(rollbackFor = { Exception.class })
public class GenericHibernateDAO<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDAO <T, PK>
{
    @Override
    public Serializable create(final T instance)
    {
        return this.getHibernateTemplate().save(instance);
    }

    @Override
    public void update(final T instance)
    {
        this.getHibernateTemplate().saveOrUpdate(instance);
    }

    @Override
    public T findById(final Class <T> clazz, final PK id)
    {
        return this.getHibernateTemplate().get(clazz, id);
    }

    ...
}

这是我对其进行修改的方式,以及它在其他模块中的工作方式:

@Transactional(rollbackFor = { Exception.class })
public class GenericHibernateDAO<T, PK extends Serializable> implements GenericDAO <T, PK>
{
    protected SessionFactory sessionFactory;

    public SessionFactory getSessionFactory()
    {
        return this.sessionFactory;
    }

    public void setSessionFactory(final SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    public Session getSession()
    {
        return SessionFactoryUtils.getSession(this.sessionFactory, true);
    }

    @Override
    public Serializable create(final T instance)
    {
        return this.getSession().save(instance);
    }

    @Override
    public void update(final T instance)
    {
        this.getSession().saveOrUpdate(instance);
    }

    @Override
    public T findById(final Class <T> clazz, final PK id)
    {
        return (T) this.getSession().get(clazz, id);
    }
    ...
}

派生DAO类的定义:

public class RepositoryFolderHibernateDAO extends GenericHibernateDAO <RepositoryFolder, Long> implements RepositoryFolderDAO

实体定义:

@Entity
@javax.persistence.Table(name = "repositoryfolder") 
public class RepositoryFolder
{
    @Id
    @GeneratedValue
    private long id;

    @Column(name = "repository_id", nullable = false)
    private long repositoryId = 1L;

    @Column(name = "parent_id", nullable = true)
    private Long parent;

    @Column(length = 255, nullable = false)
    private String name;

    @Column(length = 255, nullable = true)
    private String description;

    @Cascade(value =
    { org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "id.folderId")
    private Set <MandatorFolderRight> mandatorFolderRights = new HashSet <MandatorFolderRight>();

    public RepositoryFolder()
    {
        super();
    }

        ... more c'tors and getters/setters
}

使用HibernateDao + HibernateTemplate来执行所有更新,但是没有忽略它们,只是创建和删除操作起作用。 我一直在搜索几天,但找不到这种奇怪行为的任何原因。在这两种情况下,Bean的定义也相同。

还有没有其他人遇到过这个问题并找到了解决方案?

0 个答案:

没有答案