I have two entity, Promotion which contains information about a promotion and Promotion Details which contains list of products in a Promotion. Below is my code.
Promotion Entity:
@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:
@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;
}
I want to retrieve one Promotion which is available for a product using 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);
}
But this error occured:
Stacktrace:
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)
I know it seems like Promotion is calling PromotionDetails and PromotionDetails is calling Promotion and so on. But, how do I fix this?
--EDIT--
I would like to add something. I am using Lombok to generate Getter, Setter, and toString
You can exclude fields from the ToString generation in Lombok. For that, you have to add the @ToString annotation to your class and add the fields, which you want to exclude. In your case, i would exclude the field details in the Promotion class:
@ToString(exclude="details")
public class Promotion {}
com.example.entity.PromotionDetails.toString(PromotionDetails.java:18)
.
.
.
jp.co.worksap.stm.entity.sales.Promotion.toString(Promotion.java:18)
You have a recursive call on the toString() of both entities I guess,
PromotionDetails is trying to print Promotion while Promotion is trying to print all its PromotionsDetails
A solution would be :
Remove either Promotion value from the PromotionDetails toString() method or remove PromotionDetails from the toString() of Promotion.
Becareful with toString() presentation of entities it can cause you trouble.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With