Hibernate OneTomany java.lang. StackOverflow 错误

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

我正在尝试建立一对多的冬眠关系。当我试图从数据库中获取一些数据时,我得到了 StackOverlowError。但是,当我删除一对多的一部分,一切正常。这是我的 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<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,我才能解决这个问题。我已经像下面这样覆盖了 TeamandLeague 的 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));
}
58925 次浏览

它抛出 StackOverFlow 的唯一方法是当您的团队的联盟被递归访问时... ..。

团队对团队对团队

我猜想有一些函数试图将您的对象转换为其他反射或递归的表示形式,从而产生一个无限循环。

我也有过类似的问题。我在我的模型对象上使用龙目岛的 @Data注释来自动生成 getter,setter 和其他标准方法。我相信龙目岛生成的 toString()方法在我的 TeamLeague对象之间引入了一个循环依赖关系。当我试图从我的 League对象获取 Set<teams> teams时,我得到了一个 java.lang.StackOverflowError,因为 Spring 调用 toString 方法来记录日志。

为了解决这个问题,我放弃了龙目岛的 toString()方法。我用龙目岛的 @Getter@Setter注释代替了 @Data注释。这样,我仍然可以从免费的 getter 和 setter 中受益,而不需要使用 toString()方法。

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

有助于这一方法:

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

Name = “ order _ id”是 Product 表中的外键列。

我没有在产品实体中放任何东西。

如果使用 @Data复杂的注释,循环依赖可以源自 龙目岛 toString()自动生成的方法。为某个字段排除循环依赖项:

@Entity
@Data
public class Team {


...


@ToString.Exclude
@ManyToOne
private League league;
}

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

您可以使用这个注释来排除 equalsAndHasCode 的成员,只需要一个注释:

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

同样,如果你想从 equals 方法中排除成员,龙目岛提供: @ToString.Exclude

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

之所以出现这个错误,是因为我使用 jackson 解析了映射到 @OneToMany@ManyToOne两侧到 json 的对象列表,这导致了一个无限循环。

如果您处于相同的情况下,您可以通过使用 @JsonManagedReference@JsonBackReference注释来解决这个问题。

API 的定义:

例如:

拥有者.java:

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

返回文章页面

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

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

我用龙目岛的@Getter 和@Setter 注释替换了@Data 注释

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

另见: Hibernate 在查询时抛出 StackOverflow 错误

在我的例子中,我对一个实体使用 @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并急切地加载所有 MyEntity时,Hibernate 再次加载父实体 Foo,同时构建导致堆栈溢出的密钥。

我通过使用显式的键属性(即包括 MyEntityKey中 Foo 的键而不仅仅是对 Foo的引用)对 id 进行建模来解决这个问题,如 复合密钥处理,在 Spring 引导 java 中使用@ID 类注释所示(也适用于 Non-Spring Hibernate)。简而言之: 使用 @JoinColumns注释指定导航属性(到父)和 id 列之间的关系。

我挣扎了很长时间,认为这是一个来自 Kotlin 的问题,为什么它会抛出一个堆栈溢出异常。最后是 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;
}
}

最后是另一端,这导致了堆栈溢出异常。

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

在休眠状态的 OneToOne 映射中出现这个错误,Entity 类无法转换为 String。

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。 需要移除其中一个。 那么这个问题就解决了。

我发现使用@EqualsAndHashCode (onlyExplicity lyinclude = true)是一个很好的起点。在大多数情况下,对象之间的相等只能在特定的值上进行。如果对每个实体都使用这个参数,那么它将强制您选择在等式中实际想要包含的内容,并且很可能会阻止循环内存引用。

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

要允许双方使用,请在实体中使用 @JsonIdentityInfo注释,并删除 @JsonBackReference@JsonManagedReference。你们这些实体会是这样的:

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

这个代替了我要找的圆形引用。

我在使用龙目岛时也遇到过类似的问题。它在我的@EqualsAndHashCode 中,因此您可以按属性名排除子集合:

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

我在“ Spring Data Rest”和 Lomboks@Data 注释的组合中遇到了同样的问题 @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<>();
}

这招对我很管用。 谢谢 Neeraj Jain。