简体   繁体   English

Hibernate OneToMany java.lang.StackOverflowError

[英]Hibernate OneToMany java.lang.StackOverflowError

It's my first question here on stack, so please be gentle:D这是我在堆栈上的第一个问题,所以请温柔:D

I'm trying to create hibernate OneToMany relationship.我正在尝试创建 hibernate OneToMany 关系。 When I try to fetch some data from my DB, I'm getting StackOverflowError.当我尝试从我的数据库中获取一些数据时,我得到了 StackOverflowError。 But when i remove OneToMany part, everything goes normally.但是当我删除 OneToMany 部分时,一切正常。 This is part of my REST Service, for now it runs on VMware vFabric Server and MySQL DB.这是我的 REST 服务的一部分,目前它在 VMware vFabric 服务器和 MySQL DB 上运行。

Fetch example:获取示例:

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

MySQL script: 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;

Classes:课程:

@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<Team> teams;
}

Error:错误:

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

Edit:编辑:

I was able to solve this out thanks to @Thihara and @KarIP.感谢@Thihara 和@KarIP,我能够解决这个问题。 I have overriden toString() for Team and League like this:我已经为 Team 和 League 覆盖了 toString(),如下所示:

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

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

and was able to fetch data from DB as wanted.并且能够根据需要从数据库中获取数据。 But then while parsing I got JAXB error with infinite cycles.但是在解析时,我得到了无限循环的 JAXB 错误。 So i annotated Team and League class with @XmlAccessorType(XmlAccessType.FIELD) , so it won't look at methods, and Team league field as @XmlTransient , so it won't be parsed.所以我用@XmlAccessorType(XmlAccessType.FIELD)注释了 Team and League class ,所以它不会查看方法,而 Team league字段为@XmlTransient ,所以它不会被解析。

Here I can even remove my toString() implementations, and it still works.在这里,我什至可以删除我的 toString() 实现,它仍然有效。 I'm not completely sure why.我不完全确定为什么。 Problem is solved, but I would like to hear more precise explanation.问题已解决,但我想听听更准确的解释。 I don't know why JAXB stopped data fetch, even if it's after whole DB communication process(or isn't?).我不知道为什么 JAXB 停止数据获取,即使它是在整个数据库通信过程之后(或者不是?)。 To be more specific, I'm using Jersey for that:更具体地说,我为此使用 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));
}

I had a very similar issue.我有一个非常相似的问题。 I was using Lombok's @Data annotation on my model objects to auto-generate getters, setters, and other standard methods.我在模型对象上使用 Lombok 的@Data注释来自动生成 getter、setter 和其他标准方法。 I believe the toString() method generated by Lombok introduced a circular dependency between my Team and League objects.我相信 Lombok 生成的toString()方法在我的TeamLeague对象之间引入了循环依赖。 When I tried to get the Set<teams> teams from my League object, I got a java.lang.StackOverflowError because Spring was calling the toString method for logging purposes.当我试图从我的League对象中获取Set<teams> teams ,我得到了一个java.lang.StackOverflowError因为 Spring 正在调用 toString 方法进行日志记录。

I resolved this by getting rid of Lombok's toString() method.我通过摆脱 Lombok 的toString()方法解决了这个问题。 I replaced the @Data annotation with Lombok's @Getter and @Setter annotations.我用 Lombok 的@Getter@Setter注释替换了@Data注释。 That way I still could benefit from free getters and setters without getting the toString() method.这样我仍然可以从免费的 getter 和 setter 中受益,而无需获得toString()方法。

The only way it can throw an StackOverFlow is when your Team's League is accessed recursively....它可以抛出 StackOverFlow 的唯一方法是递归访问您团队的联赛......

Team to League to Team to League球队对联赛球队对联赛

I'm guessing there's some function trying to convert your objects into some other representation reflectively or recursively resulting in an infinite loop.我猜有一些函数试图将您的对象反射或递归地转换为其他表示形式,从而导致无限循环。

Circular dependency can originate from Lombok's toString() autogenerated method, if you use @Data complex annotation.如果您使用@Data复杂注释,循环依赖可以源自Lombok 的toString()自动生成方法。 To exclude your circular dependecy for a certain field:要排除某个字段的循环依赖:

@Entity
@Data
public class Team {

  ...

  @ToString.Exclude
  @ManyToOne
  private League league;
}

I had this error because I was parsing a list of objects mapped on both sides @OneToMany and @ManyToOne to json using jackson which caused an infinite loop.我遇到此错误是因为我正在使用 jackson 将映射在@OneToMany@ManyToOne两侧的对象列表解析为 json,这导致了无限循环。

If you are in the same situation you can solve this by using @JsonManagedReference and @JsonBackReference annotations.如果您处于相同的情况,则可以使用@JsonManagedReference@JsonBackReference注释来解决此问题。

Definitions from API :来自 API 的定义:

Example:例子:

Owner.java:所有者.java:

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

Car.java:汽车.java:

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

Another solution is to use @JsonIgnore which will just set null to the field.另一种解决方案是使用@JsonIgnore ,它只会为该字段设置 null 。

For me, Both hashCode and toString default implementation provided by Lombok was causing this issue.对我来说,Lombok 提供的 hashCode 和 toString 默认实现都导致了这个问题。

You can use this annotation to exclude members for both equalsAndHasCode with single annotation:您可以使用此注释通过单个注释排除 equalsAndHasCode 的成员:

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

Also if you want to exclude just members from equals method, Lombok provide : @ToString.Exclude此外,如果您只想从 equals 方法中排除成员,Lombok 提供: @ToString.Exclude

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

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

I had similar issue and in my case nothing of this didnt help.我有类似的问题,在我的情况下,这没有任何帮助。

Helped this one approach:帮助了这种方法:

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

name = "order_id" is a foreign key column from Product table. name = "order_id" 是 Product 表中的外键列。

And i didnt put anything in Product entity.而且我没有在 Product 实体中放入任何东西。

I struggled a very long time and thought it's a problem from Kotlin why it throws an Stackoverflow Exception.我挣扎了很长时间,并认为这是 Kotlin 的一个问题,为什么它会抛出 Stackoverflow 异常。 At the end it was Jackson, which is used by Spring Hibernate and causese the Stackoverflow.最后是杰克逊,它被 Spring Hibernate 使用并导致 Stackoverflow。

You can solve that by setting @JsonIgnoreProperties on both sides.您可以通过在两侧设置@JsonIgnoreProperties来解决该问题。 Example:例子:

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

and finally the other side, which caused the stackoverflow exception.最后是另一边,这导致了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;
}
}

When i was having this problem i was converting the entity to dto.当我遇到这个问题时,我正在将实体转换为 dto。 I then realized i was calling the parent class annotated with onetomany from the bridge class annotated with manytoone.然后我意识到我正在从用 manytoone 注释的桥类调用用 onetomany 注释的父类。 Because the parent already calls the bridge, it became cyclic and the collection recursed.因为父级已经调用了桥,它变成了循环并且集合递归。 Instead of calling the parent method that populates, i just initialized and populated the parent in the child.我没有调用填充的父方法,而是在子中初始化并填充父方法。

Also see: Hibernate throws StackOverflowError when querying另请参阅: Hibernate 在查询时抛出 StackOverflowError

In my case, I was using the @IdClass annotation on an entity which had a foreign key as part of its primary key:就我而言,我在一个实体上使用了@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;
  
   //...
}

Now when loading Foo and eagerly loading all MyEntity s, Hibernate was again loading the parent entity Foo while building the key which resulted in the stack overflow.现在,当加载Foo并急切加载所有MyEntity ,Hibernate 在构建导致堆栈溢出的键时再次加载父实体Foo

I fixed the issue by modelling the id using explicit key properties (ie including the keys of Foo in MyEntityKey rather than just a reference to Foo ) as shown in Composite key handling, using @Idclass annotation in Spring boot java (also applied to Non-Spring Hibernate).我通过使用显式键属性(即在MyEntityKey包含 Foo 的键,而不仅仅是对Foo的引用)对 id 进行建模来解决该问题,如复合键处理中所示, 在 Spring boot java 中使用 @Idclass 注释(也适用于非春季休眠)。 In short: Use the @JoinColumns annotation to specify the relationship between the navigation property (to parent) and the id columns.简而言之:使用@JoinColumns注释来指定导航属性(到父级)和 id 列之间的关系。

Got this error in OneToOne mapping in hibernate, the Entity class was unable to convert toString.在休眠的 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;

Error- because Class A is calling Class B and similarly, class B is calling Class A. Need to remove one of the two.错误 - 因为 A 类正在调用 B 类,类似地,B 类正在调用 A 类。需要删除两者之一。 Then this issue will be resolved.那么这个问题就会得到解决。

When I was having this problem, I could solve it with @JsonManagedReference and @JsonBackReference , however it meant that only one side of the entity had the child in it when deserializing into json.当我遇到这个问题时,我可以使用@JsonManagedReference@JsonBackReference解决它,但这意味着在反序列化为 json 时,只有实体的一侧有子项。 Ie in your team and league example, Only the League would show teams, and the team wouldnt show which league it belonged to.即在您的球队和联赛示例中,只有联赛会显示球队,而球队不会显示它属于哪个联赛。

To allow both side, use @JsonIdentityInfo annotation in your entity and remove the @JsonBackReference and @JsonManagedReference .要允许双方, @JsonIdentityInfo在您的实体中使用@JsonIdentityInfo注释并删除@JsonBackReference@JsonManagedReference You entities will be something like:您的实体将类似于:

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

This replaced the circular refrences with what I was looking for.这用我正在寻找的替换了循环引用。

I find that using @EqualsAndHashCode(onlyExplicitlyIncluded = true) is a great place to start.我发现使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true) 是一个很好的起点。 In most cases, equality across objects should only be done on specific values.在大多数情况下,对象之间的相等性应该只对特定值进行。 If you use this for every entity, it will force you to choose what you actually want to include in equality, and is likely to preven the circular memory reference.如果你对每个实体都使用它,它将迫使你选择你真正想要包含在平等中的内容,并且可能会阻止循环内存引用。

I had a similar problem using Lombok on a save and flush.我在保存和刷新时使用 Lombok 遇到了类似的问题。 It was in my @EqualsAndHashCode, so you can exclude child collections by property name:它在我的@EqualsAndHashCode 中,因此您可以按属性名称排除子集合:

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

I had the same issue in the combination of "Spring Data Rest" and Lomboks @Data annotation.我在“Spring Data Rest”和 Lomboks @Data 注释的组合中遇到了同样的问题。 Definitely use both @ToString.Exclude @EqualsAndHashCode.Exclude My setup:绝对同时使用@ToString.Exclude @EqualsAndHashCode.Exclude我的设置:

@RepositoryRestResource(collectionResourceRel = "a", path = "a")
public interface ARepository extends JpaRepository<A, Long> {
}

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    @Entity
    @EntityListeners(AuditingEntityListener.class)
    @EqualsAndHashCode(callSuper = true)
    public class A extends AuditMetadata<String> {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String x;
        private String y;

        @ToString.Exclude
        @EqualsAndHashCode.Exclude
        @ManyToOne
        private B b;
    
    }

@RepositoryRestResource(collectionResourceRel = "b", path = "b")
public interface BRepository extends JpaRepository<B, Long> {
}

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    @Entity
    @EqualsAndHashCode(callSuper = true)
    public class B extends AuditMetadata<String> {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String k;
        private String l;
        private String m;
        @OneToMany(mappedBy = "b", cascade = CascadeType.ALL)
        private Set<A> aList = new HashSet<>();
    }

This worked for me perfectly.这对我来说非常有效。 Thanks Neeraj Jain.谢谢尼拉杰耆那教。

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

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