Hibernate使用延迟加载删除@ManyToMany关系中的关系

时间:2013-08-28 06:47:16

标签: 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 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;
        }
    }

第二个:

@Entity
@Table(name="B")
public class B extends AbstractBO {

    private List<A> a;

    @Override
    @Id
    public String getId(){
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @ManyToMany(targetEntity=A.class, fetch=FetchType.LAZY, mappedBy="b")
    public List<A> getAs() {
        return a;
    }

    public void setAs(List<A> a) {
        this.a = a;
        }
}

我的hibernate.cfg.xml是:

<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>

到目前为止,一切正常。可以保存,更新,删除和加载数据库及其所有子项中持久存在的所有对象。如果我正在加载A类型的对象,在前端包含getBs(),则会显示正确的一个及其所有子项。但是hibernate做了“Hibernate:从A_B删除B_id =?”紧跟在SELECT语句之后。这将删除对象及其子对象之间的所有关系。 如果我将FetchType的{​​{1}}更改为“EAGER”,一切正常。看来,hibernate消除了这样一个事实,即没有调用B子对象。

我还尝试将班级getAs()的{​​{1}}更改为:

getAs()

顺便说一下,我正在使用:

  • hibernate 4.2.4 final
  • JSF 2.0
  • JPA 2.0

我已阅读了许多相关文章,并尝试了与Cascade等不同的建议。此外,我考虑在B的构造函数中调用@JoinTable(name="A_B", joinColumns={@JoinColumn(name="B_id")}, inverseJoinColumns={@JoinColumn(name="A_id")}) public List<A> getAs() {[...] ,但所有这些都无法解决我的问题。 / p>

在对我的应用程序进行debbuging时,我在类getAs()的getter中添加了一行:

B

调用B不会改变任何内容。因为一切都突然起作用,我感到很困惑。因此,作为结论,我的应用程序现在可以使用此“修复”。但如果有人能给我一个更常见的解决方案,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

当您启用hibernate.enable_lazy_load_no_trans并且错误仍处于打开状态时,我猜您是HHH-7971的受害者。我无法为此提供适当的解决方案,如果行为是此错误的结果,您可以使用解决方法来修复它。

我想a.size()修复了这个问题,因为Hibernate代理在那一刻被初始化了。因此,使用Hibernate.initialize(a)更合适。此外,我不会在吸气器中这样做,而是在你称之为吸气剂的地方。