2013-02-21 73 views
0

我使用的是hibernate 3.6,XML映射。Hibernate merge()与版本号

从下面的模式开始。

public class Card { 
    @IndexedEmbedded 
    private CardType cardType; 

    private User user;//many-to-one 
    ... 
} 

public class User { 
    ... 
    private int version;//Need to be strict about version on this table 
    private Set<Card> cards = new HashSet<Card>();//cascade="all-delete-orphan" 
    ... 
} 

如果我做到以下几点:
1:加载现有用户
2:关闭会话,工作脱管状态的客户端。添加瞬时标签。
3:将用户返回给服务器,openSession(),beginTransaction(),saveOrUpdate(用户),commit()。

我得到以下错误 “错误而索引在Hibernate Search的(交易完成前)” ... 造成的:org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话

到目前为止这对我来说很有意义。 CardType &卡需要更新其索引。所以我希望在saveOrUpdate()之前将第3步更改为merge()。

如果我这样做,它会将分离的所有属性(包括版本)复制到会话感知对象中。这当然意味着我的乐观锁定策略失败 - 没有警告版本问题。

在这种情况下应该采取的策略是什么?

--Post更新,以显示一些会话处理代码 -

public synchronized static SessionFactory getSessionFactory() { 
    if (sessionFactory == null) { 
    final AuditLogInterceptor interceptor = new AuditLogInterceptor(); 
    Configuration configuration = new Configuration(); 
    configuration = configuration.configure("hibernate.cfg.xml"); 
    configuration.setInterceptor(interceptor); 
    sessionFactory = configuration.buildSessionFactory(); 
    AbstractSessionAwareConstraintValidator.setSessionFactory(sessionFactory); 
    } 
    return sessionFactory; 
} 

测试代码是这样的

sessionFactory = HibernateUtil.getSessionFactory(); 
sessionFactory.getCurrentSession().beginTransaction(); 
//Find user here 
sessionFactory.getCurrentSession().getTransaction().commit(); 
sessionFactory.getCurrentSession().close(); 
//Edit User, add tags out of session. (not using OSIV) 
sessionFactory.getCurrentSession().beginTransaction(); 
user = sessionFactory.getCurrentSession().merge();//Only works if I do this 
sessionFactory.getCurrentSession().saveOrUpdate(entity); 
sessionFactory.getCurrentSession().getTransaction().commit(); 
sessionFactory.getCurrentSession().close(); 

至于林知道有什么“非标”在我的休眠.cfg.xml,但只列出这3行线程 org.hibernate.cache.NoCacheProvider

我希望有足够的代码来演示会话使用情况。发布了这个后,我想知道拦截器是否可能影响会话管理?

+0

为什么会失败?你想要你的版本属性被复制。这正是保证如果该版本已被其他用户修改的情况下刷新会抛出异常的原因。 – 2013-02-21 10:31:56

+0

我不觉得LazyInitializationException正常...我怀疑在事务设置 – 2013-02-21 10:34:47

+0

JB Nizet有一些问题,你当然是对的。我不知道我在那里想什么。那么问题仍然存在,是合并的正确的做法还是有其他原因我得到了艾德里安建议的LazyInitException? Hibernate Search在完成之前是否应该在新会话中做它所需要的? – user2046211 2013-02-21 12:01:14

回答

0

你如何处理会议?在索引期间,会话必须仍然处于打开状态,以便索引器可以加载延迟加载的关联。在webapps中,开放会话视图模式通常用于在整个请求过程中打开一个会话。你需要发布一些更具体的代码来获得更具体的反馈。另一种方法是急于加载关联(可能不是一个好主意)。

+0

另请参阅http://stackoverflow.com/questions/979809/hibernate-search-problem-could-not-initialize-proxy-no-session – Hardy 2013-02-22 10:31:40