简体   繁体   English

Spring + Hibernate:以多对多关系保存和获取数据

[英]Spring + Hibernate: saving and fetching data in many-to-many relation

I'm using Spring 3 + Hibernate and I have two entities (User, Address) related each other with the relation @ManyToMany. 我正在使用Spring 3 + Hibernate,并且我有两个相互关联的实体(用户,地址),它们之间的关系为@ManyToMany。 Every entity is mapped on a table ('user' and 'address') and the relation is defined by a linktable 'user_address' that maps user_id and address_id. 每个实体都映射到一个表(“用户”和“地址”)上,并且该关系由映射表user_id和address_id的链接表“ user_address”定义。

I have "method1" that saves 'User' when new address is added: 我有添加新地址时保存“用户”的“ method1”:

@Transactional
public void method1 (...) {
   /* do something*/
   user.getAddresses().add(address);
   session.save(user);
}

in another method2 I need to retrieve for a specific user, an address by the street: 在另一种方法2中,我需要为特定用户检索街道旁的地址:

@Transactional
public Address method2 (Long userId, String streetName) {
   String hql = "select distinct a from Address a " +
            "join a.users u " +
            "where u.id=:id and a.name=:name";
            Query query = session.createQuery(hql);
            query.setParameterList("id", userId);
            query.setParameterList("name", streetName);
            Address address = query.uniqueResult();
            return address;
}

The problem in this situation is when a new address is added via method1 it still may be in the cache when method2 is executed (so no address is returned) as method2 hits the database (that could be out-of-sync respect to cache). 这种情况下的问题是,当通过method1添加新地址时,由于method2命中数据库(执行时与缓存不同步),当执行method2(因此不返回地址)时,它仍可能位于高速缓存中。 The only solution I found is adding a "flush" after method1 but I don't really like it. 我发现的唯一解决方案是在method1之后添加“ flush”,但我真的不喜欢它。 Do you know a better way to do it? 您知道更好的方法吗?

Calling a session.flush() manually in some methods is not a bad idea, at least for me. 至少对于我来说,在某些方法中手动调用session.flush()并不是一个坏主意。

There are alternatives: 还有其他选择:

  • Set Hibernate FlushMode to AUTO or ALWAYS (try AUTO first, should prevent stale results in queries, ALWAYS is to expensive to be useful) 将Hibernate FlushMode设置为AUTO或ALWAYS(首先尝试AUTO,应防止查询中出现过时的结果,ALWAYS太昂贵了才有用)
  • Set PROPAGATION level to REQUIRES_NEW in Transactional annotation of method1: Will commit the method1 always, suspend current trasaction and createa new one to add the user. 在method1的Transactional注释中将PROPAGATION级别设置为REQUIRES_NEW:将始终提交method1,暂停当前事务并创建一个新用户以添加用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM