【问题标题】:How to delete records from two tables with `@OneToMany` relation?如何从具有“@OneToMany”关系的两个表中删除记录?
【发布时间】:2015-03-13 17:43:47
【问题描述】:

我正在使用 JPA 和 Spring Data 来执行 CRUD 操作。在下面找到详细信息:

主表:

@Entity
@Table(name = "university")
public class University implements Serializable {
    @OneToMany(mappedBy = "pk.university", 
               cascade = CascadeType.ALL, 
               fetch = FetchType.EAGER)
    private Set<Student> tagDetailReaders = new HashSet<Student>(0);
}

外键表:

@Entity
@Table(name = "student")
@AssociationOverrides({ @AssociationOverride(name = "pk.university", joinColumns = @JoinColumn(name = "university_id")) })
public class Student implements Serializable {

}

删除记录的Spring数据代码:

University entity = universityDao.findAll().get(0);
universityDao.delete(entity);

我收到以下错误:

java.lang.StackOverflowError
    at java.net.DualStackPlainSocketImpl.socketAvailable(Unknown Source)
    at java.net.AbstractPlainSocketImpl.available(Unknown Source)
    at java.net.SocketInputStream.available(Unknown Source)
    at com.mysql.jdbc.util.ReadAheadInputStream.available(ReadAheadInputStream.java:230)
    at com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:954)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2531)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2758)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2826)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2212)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2065)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
    at org.hibernate.loader.Loader.doQuery(Loader.java:909)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:324)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:2148)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:78)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:68)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213)
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)

有人可以告诉我为什么会出现 stackoverflow 错误吗?

注意:如果我将获取类型从EAGER 更改为LAZY 并设置orphanRemoval=true,它工作正常。请让我知道这是否是解决此问题的唯一方法?

【问题讨论】:

    标签: spring jpa spring-data-jpa


    【解决方案1】:

    findAll() 方法正在加载与所有大学关联的所有学生,这可能是您收到 StackOverflow 错误的原因。这就是为什么当您使用 LAZY fetch-type 时它会消失的原因,因为最初不会加载所有学生。

    【讨论】:

      猜你喜欢
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 2017-05-29
      • 2015-05-05
      • 2014-01-10
      • 1970-01-01
      相关资源
      最近更新 更多