【问题标题】:Hibernate OneToMany java.lang.StackOverflowError休眠 OneToMany java.lang.StackOverflowError
【发布时间】:2013-07-01 00:07:39
【问题描述】:

这是我在堆栈上的第一个问题,所以请温柔:D

我正在尝试创建休眠的 OneToMany 关系。当我尝试从我的数据库中获取一些数据时,我得到了 StackOverflowError。但是当我删除 OneToMany 部分时,一切正常。这是我的 REST 服务的一部分,目前它在 VMware vFabric Server 和 MySQL DB 上运行。

获取示例:

@Inject
private EntityManager entityManager;
...
entityManager.find(League.class, 1);
...
entityManager.find(Team.class, 1);

MySQL 脚本:

CREATE TABLE league (
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(20) COLLATE utf8_unicode_ci NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE team (
    team_id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(20) COLLATE utf8_unicode_ci NOT NULL,
    fk_leagueId int(11) NOT NULL,
    PRIMARY KEY (team_id),
    FOREIGN KEY (fk_leagueId) REFERENCES league(id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

类:

@XmlRootElement
@Entity
@Table(name = "team")
@Data
public class Team {
    @Id
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    @Column(name = "team_id")
    private int id;
    @Column(name = "name")
    private String name;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_leagueId", nullable = false)
    private League league;
}

@XmlRootElement
@Entity
@Table(name = "league")
@Data
public class League {
    @Id
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    //if I comment 2 lines below, there is no error, and everything works fine
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "league")
    private Set<span><</span>Team> teams;
}

错误:

Hibernate: select league0_.id as id1_1_0_, league0_.name as name2_1_0_ from league league0_ where league0_.id=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Hibernate: select teams0_.fk_leagueId as fk3_1_1_, teams0_.team_id as team1_4_1_, teams0_.team_id as team1_4_0_, teams0_.fk_leagueId as fk3_4_0_, teams0_.name as name2_4_0_ from team teams0_ where teams0_.fk_leagueId=?
Exception in thread "tomcat-http--3" java.lang.StackOverflowError
    at org.jboss.logging.JDKLogger.translate(JDKLogger.java:73)
    at org.jboss.logging.JDKLogger.isEnabled(JDKLogger.java:85)
    at org.jboss.logging.JDKLogger.doLog(JDKLogger.java:41)
    at org.jboss.logging.Logger.debug(Logger.java:406)
    at org.hibernate.internal.CoreMessageLogger_$logger.debug(CoreMessageLogger_$logger.java:525)
    at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:104)
    at org.hibernate.engine.jdbc.spi.SqlStatementLogger.logStatement(SqlStatementLogger.java:95)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:180)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:159)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1858)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1835)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1815)
    at org.hibernate.loader.Loader.doQuery(Loader.java:899)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:311)
    at org.hibernate.loader.Loader.loadCollection(Loader.java:2234)
    at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:65)
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:674)
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:83)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1849)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:549)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:234)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
    at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:428)
    at com.lukaszb.motspe.webapp.model.League.hashCode(League.java:21)
    at com.lukaszb.motspe.webapp.model.Team.hashCode(Team.java:20)
    at java.util.HashMap.hash(HashMap.java:351)
    at java.util.HashMap.put(HashMap.java:471)
    at java.util.HashSet.add(HashSet.java:217)
...

编辑:

感谢@Thihara 和@KarIP,我能够解决这个问题。我已经像这样覆盖了 Team 和 League 的 toString():

@Override
public String toString() {
    return "League [id=" + id + ", name=" + name + "]";
}

@Override
public String toString() {
    return "Team [id=" + id + ", name=" + name + "]";
}

并且能够根据需要从数据库中获取数据。但是在解析时,我得到了无限循环的 JAXB 错误。所以我用@XmlAccessorType(XmlAccessType.FIELD)注释了Team和League类,所以它不会看方法,而Team league字段为@XmlTransient,所以它不会被解析。

在这里我什至可以删除我的 toString() 实现,它仍然有效。 我不完全确定为什么。 问题已解决,但我想听听更准确的解释。我不知道为什么 JAXB 停止数据获取,即使它是在整个 DB 通信过程之后(或者不是?)。 更具体地说,我为此使用 Jersey:

@GET
@Path("search/id")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public List<League> searchById(@QueryParam("id") int id) {
return Arrays.asList(leagueDAO.getById(id));
}

【问题讨论】:

  • 在您的联赛课程中,您已经定义了一组团队,但在其 getter 和 setter 上添加了一对多注释
  • 这是一个很好的问题,所以为你投票。\
  • 类似问题及解决方法:stackoverflow.com/questions/17195116/…

标签: java hibernate stack-overflow one-to-many


【解决方案1】:

我有一个非常相似的问题。我在我的模型对象上使用 Lombok 的 @Data 注释来自动生成 getter、setter 和其他标准方法。我相信 Lombok 生成的 toString() 方法在我的 TeamLeague 对象之间引入了循环依赖。当我尝试从League 对象中获取Set&lt;teams&gt; teams 时,我得到了java.lang.StackOverflowError,因为Spring 正在调用toString 方法进行日志记录。

我通过摆脱 Lombok 的 toString() 方法解决了这个问题。我用 Lombok 的 @Getter@Setter 注释替换了 @Data 注释。这样我仍然可以从免费的 getter 和 setter 中受益,而无需使用 toString() 方法。

【讨论】:

  • 谢谢,这有帮助。或者,您仍然可以使用 @Data 注释,但添加 @ToString 注释并指定排除属性,如:@ToString(exclude = { "propName" })
  • 老兄,你是救生员。谢谢!!
  • 谢谢!我永远不会猜到 Lombok 的 @Data 会导致这种情况。
  • 这对我有帮助。我卡住了。谢谢!
  • 谢谢你拯救了我的一天!
【解决方案2】:

它可以抛出 StackOverFlow 的唯一方法是递归访问您的 Team's League....

团队到联赛到团队到联赛

我猜有一些函数试图将你的对象反射或递归地转换为其他表示,从而导致无限循环。

【讨论】:

  • 谢谢,这给了我一个解决方案。
  • 感谢您的建议!对我来说,它是一个多对多 id 类中的 hashCode
  • 在遇到类似问题时偶然发现了这一点。我几乎有这个问题中提到的确切关系,问题不仅发生在 toString() 上,而且(在我的情况下)LomBok 提供的哈希码默认实现也发生了。我的直接解决方案是从 toString() 和 hashcode() 中排除有问题的字段,但也考虑将拥有 OneToMany 关系转移到“One”端,这可能有助于解决问题,但是这个可能会让你措手不及,没有适当的围绕您的应用程序进行端到端测试!
  • 在我的例子中 toString() 方法有递归调用。
  • 天哪。从今天早上开始,我一直在尝试解决这个问题。没有意识到龙目岛是罪魁祸首。谢谢你拯救了我的一天。
【解决方案3】:

循环依赖可以源自 Lombok 的 toString() 自动生成方法,如果您使用 @Data 复杂注解。要排除您对某个字段的循环依赖:

@Entity
@Data
public class Team {

  ...

  @ToString.Exclude
  @ManyToOne
  private League league;
}

【讨论】:

  • +1 用于使用@ToString.Exclude(和@EqualsAndHashCode.Exclude)——比@...(exclude = {"children"}) 品种好得多。
【解决方案4】:

我遇到此错误是因为我正在使用 jackson 将映射在两侧 @OneToMany@ManyToOne 的对象列表解析为 json,从而导致无限循环。

如果您遇到同样的情况,您可以使用@JsonManagedReference@JsonBackReference 注释来解决此问题。

API 定义:

例子:

Owner.java:

@JsonManagedReference
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
Set<Car> cars;

Car.java:

@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;

另一种解决方案是使用 @JsonIgnore,它只会将字段设置为 null。

【讨论】:

  • 如果我在 fetch 时仍然希望拥有 Car 对象中的 Owner 怎么办?我需要拥有车主,也需要车主,这是否可能不做一些 DTO 和烦人的映射?
  • @Jessy,您可以使用 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") 代替循环引用,只需一个 id
  • 这在实体到 DTO 转换时解决循环依赖问题很有效
【解决方案5】:

对我来说,Lombok 提供的 hashCode 和 toString 默认实现都导致了这个问题。

你可以使用这个注解来排除带有单个注解的 equalsAndHasCode 的成员:

@EqualsAndHashCode(exclude = {"certificates", "payment"})

此外,如果您只想从 equals 方法中排除成员,Lombok 提供:@ToString.Exclude

@ToString.Exclude
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "shipment")
    private Set<Certificate> certificates;

【讨论】:

  • 非常感谢这解决了我的问题,我们也可以在属性上使用@EqualsAndHashCode.Exclude
  • 给这个人一块饼干。谢谢你,先生。但是垃圾收集是怎么回事,我们删除对象有问题吗?
【解决方案6】:

我用 Lombok 的 @Getter 和 @Setter 注释替换了 @Data 注释

【讨论】:

  • 您应该制作一个完整的代码示例来说明您所做的更改,说明旧代码为何不起作用以及您的解决方案如何修复它。
  • 谢谢,这个改动帮我解决了! Data 注释生成(除其他外)toString 方法考虑所有属性介绍,这意味着如果您在双向关系的两侧都有它(例如,OneToMany 和 ManyToOne),toString 方法将递归地从一个实体转到另一个实体,从而以 StackOverflow 错误结束。用 Getter 和 Setter 替换它可以避免生成这个 toString 方法,在大多数情况下,这可能是不必要的。
【解决方案7】:

我有类似的问题,在我的情况下,这没有任何帮助。

帮助了这一种方法:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "order_id")
@Fetch(value = FetchMode.SUBSELECT)
private List<Product> orderLines; 

name = "order_id" 是 Product 表中的外键列。

而且我没有在 Product 实体中放任何东西。

【讨论】:

    【解决方案8】:

    我挣扎了很长时间,并认为这是 Kotlin 的问题,为什么它会抛出 Stackoverflow 异常。最后是Jackson,它被Spring Hibernate使用并导致Stackoverflow。

    你可以通过在两边设置@JsonIgnoreProperties来解决这个问题。示例:

    public class ProductEntity implements Serializable {
    
    private List<ProductPriceEntity> refProductPriceEntities = new ArrayList<>();
    
    @OneToMany(
            mappedBy = "product",
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL,
            orphanRemoval = true,
            targetEntity = ProductPriceEntity.class)
      @JsonIgnoreProperties(value = "product", allowSetters = true)
      public List<ProductPriceEntity> getRefProductPriceEntities() {
        return refProductPriceEntities;
      }
    
      public void setRefProductPriceEntities(List<ProductPriceEntity> refProductPriceEntities) {
        this.refProductPriceEntities = refProductPriceEntities;
      }
    }
    

    最后是另一边,导致stackoverflow异常。

    public class ProductPriceEntity {
    
    private ProductEntity product;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
            @JoinColumn(name = "product_id", referencedColumnName = "id", nullable = false),
            @JoinColumn(name = "product_version_id", referencedColumnName = "version_id", nullable = false)
    })
    @JsonIgnoreProperties(value = "refProductPriceEntities", allowSetters = true)
    public ProductEntity getProduct() {
        return product;
    }
    
    public void setProduct(ProductEntity product) {
        this.product = product;
    }
    }
    

    【讨论】:

      【解决方案9】:

      当我遇到这个问题时,我正在将实体转换为 dto。然后我意识到我正在从用manytoone注释的桥类中调用用onetomany注释的父类。因为父节点已经调用了桥,所以它变成了循环的并且集合递归了。我没有调用填充的父方法,而是初始化并填充了子中的父方法。

      【讨论】:

        【解决方案10】:

        另见:Hibernate throws StackOverflowError when querying

        在我的例子中,我在一个实体上使用了 @IdClass 注释,该实体有一个外键作为其主键的一部分:

        @IdClass(MyEntity.MyEntityKey.class)
        public class MyEntity {
           public static class MyEntityKey {
               private Foo parent;
               private int count;
               // Getters, setters, constructor, ...
           }
        
           @Id
           private Foo parent;
           @Id
           private int number;
          
           //...
        }
        

        现在,当加载 Foo 并急切地加载所有 MyEntitys 时,Hibernate 在构建导致堆栈溢出的密钥时再次加载父实体 Foo

        我通过使用显式键属性(即包括 MyEntityKey 中的 Foo 的键,而不仅仅是对 Foo 的引用)对 id 建模解决了这个问题,如 Composite key handling, using @Idclass annotation in Spring boot java 所示(也适用于非 Spring Hibernate )。简而言之:使用@JoinColumns注解来指定导航属性(到父级)和id列之间的关系。

        【讨论】:

          【解决方案11】:

          在休眠的 OneToOne 映射中出现此错误,实体类无法转换为字符串。

          Class A(Details.class)-
          @OneToOne
          @JoinColumn(name="billing_address_id")
          private Address billingAddress;
          
          @OneToOne
          @JoinColumn(name="shipping_address_id")
          private Address shippingAddress;
          
          
          Class B(Address.class)-
          @OneToOne(mappedBy="billingAddress")
          private Details billingDetails;
          
          @OneToOne(mappedBy="shippingAddress")
          private Details shippingDetails;
          

          错误-因为 A 类正在调用 B 类,同样,B 类正在调用 A 类。 需要删除两者之一。 那么这个问题就解决了。

          【讨论】:

            【解决方案12】:

            当我遇到这个问题时,我可以使用@JsonManagedReference@JsonBackReference 来解决它,但这意味着在反序列化为 json 时只有实体的一侧有子元素。 IE。在您的球队和联赛示例中,只有联赛会显示球队,而球队不会显示它属于哪个联赛。

            要允许双方,请在您的实体中使用@JsonIdentityInfo 注释并删除@JsonBackReference@JsonManagedReference。您的实体将类似于:

            @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
            public class Team {
            ...
            

            这用我正在寻找的内容替换了循环引用。

            【讨论】:

              【解决方案13】:

              我发现使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true) 是一个很好的起点。在大多数情况下,对象之间的相等应该只在特定值上完成。如果您对每个实体都使用它,它将迫使您选择实际想要包含在相等性中的内容,并且可能会阻止循环内存引用。

              【讨论】:

                【解决方案14】:

                我在保存和刷新时使用 Lombok 时遇到了类似的问题。它在我的@EqualsAndHashCode 中,因此您可以按属性名称排除子集合:

                @Data
                @EqualsAndHashCode(callSuper = true, exclude = "childRowCollectionProp")
                @Entity
                @Table(name = "parent")
                public class Parent extends BaseEntityWithId{
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-07-07
                  • 2019-12-24
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-22
                  • 2011-10-31
                  • 1970-01-01
                  相关资源
                  最近更新 更多