Java Hibernate通过延迟加载删除@ManyToMany Relationship中的关系
hibernate删除两个对象之间的关系时出现问题。第一个是:Java Hibernate通过延迟加载删除@ManyToMany Relationship中的关系,java,mysql,hibernate,jpa,Java,Mysql,Hibernate,Jpa,hibernate删除两个对象之间的关系时出现问题。第一个是: @Entity @Table(name="A") public class A extends AbstractBO{ private List<B> b; @Override @Id public String getId(){ return id; } public v
@Entity
@Table(name="A")
public class A extends AbstractBO{
private List<B> b;
@Override
@Id
public String getId(){
return id;
}
public void setId(String id) {
this.id = id;
}
@ManyToMany(targetEntity=B.class, fetch=FetchType.LAZY)
@JoinTable(name="A_B", joinColumns={@JoinColumn(name="A_id")},inverseJoinColumns={@JoinColumn(name="B_id")})
public List<B> getBs() {
return b;
}
public void setBs(List<B> b) {
this.b = b;
}
}
顺便说一下,我正在使用:
- hibernate 4.2.4最终版本
- JSF2.0
- JPA2.0
B
的构造函数中调用getAs()
,但所有这些都不能解决我的问题
在清除应用程序的bug时,我在类B
的getter中添加了一行:
public List<A> getAs() {
if(a!=null) a.size();
return a;
}
公共列表getAs(){
如果(a!=null)a.size();
返回a;
}
调用
a.size()
不会改变任何东西。所以我很困惑,因为一切都突然发生了。因此,作为结论,我的应用程序现在可以使用这个“修复”。但是,如果有人能给我一个更通用的解决方案,我将不胜感激。正如你所做的那样,hibernate.enable\u lazy\u load\u no\u trans已启用,并且该漏洞仍然存在,我想你是一个漏洞的受害者。我不能给你一个合适的解决方案,如果这个行为是这个错误的结果,你可以使用一个变通方法来修复它
我猜
a.size()
解决了这个问题,因为Hibernate代理在那一刻被初始化。因此,使用Hibernate.initialize(a)
更合适。另外,我不会在getter中这样做,而是在调用getter的地方这样做。为什么建议使用Hibernate.initialize(a)?我会尝试你的建议,然后更新这个问题。一方面,它更具可读性,每个人都知道他读这行时发生了什么,另一方面,你不必做null
检查。不幸的是,Hibernate.initialize(a)不能解决这个问题。我在getter中实现了它,因为我的应用程序确实直接从前端调用了getter。运行您的建议时,关系再次被删除。顺便说一句。我已经认识到,如果hibernate在SELECT之后删除所有的不动产,并且我将调用父对象上的saveOrUpdate,那么所有的关系都将再次插入。啊,很抱歉,hibernate.initialize
不会初始化a
本身,但它会初始化a
的每个元素(它们是代理)。因此,我认为最合适的方法是调用a.size()
。每次选择后删除并重新插入不是解决此问题的好方法。
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">****</property>
<property name="hibernate.connection.release_mode">auto</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.enable_lazy_load_no_trans">true</property>
<property name="hibernate.generate_statistics">false</property>
<property name="transaction.factory_class">
org.hibernate.transaction.JDBCTransactionFactory
</property>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="de.test.A"/>
<mapping class="de.test.B"/>
</session-factory>
</hibernate-configuration>
@JoinTable(name="A_B", joinColumns={@JoinColumn(name="B_id")}, inverseJoinColumns={@JoinColumn(name="A_id")})
public List<A> getAs() {[...]
public List<A> getAs() {
if(a!=null) a.size();
return a;
}