【问题标题】:infinite recursion when querying sql using repository in jpa hibernate使用 jpa hibernate 中的存储库查询 sql 时的无限递归
【发布时间】:2016-03-01 12:41:26
【问题描述】:

我有两个实体,Promotion 包含有关促销的信息,Promotion Details 包含Promotion 中的产品列表。下面是我的代码。

推广实体:

@Entity
@Data
public class Promotion {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @OneToMany(mappedBy = "promotion")
    private List<PromotionDetails> details;

    @Column(name = "start_date")
    private Date startDate;

    @Column(name = "end_date")
    private Date endDate;
}

PromotionDetails 实体:

@Entity
@IdClass(PromotionDetailsPK.class)
@Data
public class PromotionDetails {

    @Id
    @ManyToOne(optional = false)
    @JoinColumn(name = "promotion_id", referencedColumnName = "promotion_id")
    private Promotion promotion;

    @Id
    @ManyToOne(optional = false)
    @JoinColumn(name="product_id", referencedColumnName="product_id")
    private Product product;

    @Column()
    private double discount;

}

我想检索一个Promotion,它可用于使用 JPA 的产品。

PromotionRepository:

@Repository
public interface PromotionRepository extends JpaRepository<Promotion, Long> {

    @Query("SELECT promotion "
            + "FROM Promotion promotion "
            + "INNER JOIN promotion.details details "
            + "WHERE details.product.id = :productId "
            + "AND CURRENT_DATE BETWEEN promotion.startDate AND promotion.endDate")
    Promotion findOneByProductId(@Param("productId") Long productId);

}

但是发生了这个错误:

堆栈跟踪:

Caused by: java.lang.StackOverflowError: null
    at java.lang.StringBuilder.append(Unknown Source)
    at java.lang.StringBuilder.<init>(Unknown Source)
    at com.example.entity.PromotionDetails.toString(PromotionDetails.java:18)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at java.util.AbstractCollection.toString(Unknown Source)
    at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:527)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at com.example.entity.Promotion.toString(Promotion.java:18)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at com.example.entity.PromotionDetails.toString(PromotionDetails.java:18)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at java.util.AbstractCollection.toString(Unknown Source)
    at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:527)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at com.example.entity.Promotion.toString(Promotion.java:18)
    ...
    ...
    ...
    ...
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at jp.co.worksap.stm.entity.sales.PromotionDetails.toString(PromotionDetails.java:18)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at java.util.AbstractCollection.toString(Unknown Source)
    at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:527)
    at java.lang.String.valueOf(Unknown Source)
    at java.lang.StringBuilder.append(Unknown Source)
    at jp.co.worksap.stm.entity.sales.Promotion.toString(Promotion.java:18)

我知道似乎Promotion 正在调用PromotionDetailsPromotionDetails 正在调用Promotion 等等。但是,我该如何解决这个问题?

--编辑--

我想补充一点。我正在使用 Lombok 生成 Getter、Setter 和 toString

【问题讨论】:

  • 请展示Entity Promition中的toString方法和PromotionDetails的toString方法。无限循环开始了!在 com.example.entity.Promotion.toString(Promotion.java:18)
  • 嗯,我是用lombok来生成的
  • 那么也许排除链接的实体:@ToString(exclude="id") ?

标签: java spring hibernate jpa spring-boot


【解决方案1】:

您可以从 Lombok 的 ToString 生成中排除字段。为此,您必须将 @ToString 注释添加到您的类并添加要排除的字段。在您的情况下,我会在 Promotion 类中排除字段 details

@ToString(exclude="details")
public class Promotion {}

【讨论】:

    【解决方案2】:
    com.example.entity.PromotionDetails.toString(PromotionDetails.java:18)
    .
    .
    .
    jp.co.worksap.stm.entity.sales.Promotion.toString(Promotion.java:18)
    

    我猜你对两个实体的toString() 都有一个递归调用, PromotionDetails 正在尝试打印 PromotionPromotion 正在尝试打印其所有 PromotionsDetails

    解决方案是: 从 PromotionDetails toString() 方法中删除 Promotion 值或从 toString()Promotion 中删除 PromotionDetails

    小心toString() 实体的展示,它可能会给您带来麻烦。

    【讨论】:

      猜你喜欢
      • 2015-03-14
      • 2020-06-25
      • 2018-10-02
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      相关资源
      最近更新 更多