Search code examples
spring-bootjpaspring-data-jpaflyway

How to implement One to Many relationship in Spring Boot JPA using Flyway


I want to have one-to-many relationship for the below entities.(membership_plan can have multiple membership_plan_features). I am using spring boot 3.0.6.

@Entity
@Table(name = "membership_plan")
public class MembershipPlan {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long planId;

    @Column(name = "org_id")
    private String orgId;

    @Column(name = "plan_name")
    private String planName;

    @Column(name = "plan_price")
    private String planPrice;

    @OneToMany (mappedBy = "membershipPlan")
    private List<MembershipPlanFeature> planFeature;
}

Second entity

@Entity
@Table(name = "membership_plan_feature")
@Getter
@Setter
public class MembershipPlanFeature {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "org_id")
    private String orgId;

    @Column(name = "feature_name")
    private String featureName;

    @Column(name = "feature_desc")
    private String featureDesc;

    @ManyToOne
    @JoinColumn(name="plan_id")
    private MembershipPlan membershipPlan;
}

Below are the flyway queries:

CREATE TABLE membership_plan (
   plan_id INT NOT NULL,
   org_id VARCHAR(255) NULL,
   plan_name VARCHAR(255) NULL,
   plan_price VARCHAR(255) NULL,
   PRIMARY KEY (plan_id)
   );

CREATE TABLE membership_plan_feature (
   id INT AUTO_INCREMENT NOT NULL,
   org_id VARCHAR(255) NULL,
   plan_id INT NOT NULL,
   feature_name VARCHAR(255) NULL,
   feature_desc VARCHAR(255) NULL,
   PRIMARY KEY (id)
);

ALTER table membership_plan_feature
ADD CONSTRAINT fk_membership_plan_feature
FOREIGN KEY (plan_id)
REFERENCES membership_plan (plan_id);

Now, when I query membershipPlanRepository.findAll(); it return me a recursive data:

[
    {
        "planId": 1,
        "orgId": "101",
        "planName": "GOLD",
        "planPrice": "29",
        "planFeature": [
            {
                "id": 1,
                "orgId": "101",
                "featureName": "Kanban",
                "featureDesc": "Kanban",
                "membershipPlan": {
                    "planId": 1,
                    "orgId": "101",
                    "planName": "GOLD",
                    "planPrice": "29",
                    "planFeature": [
                        {
                            "id": 1,
                            "orgId": "101",
                            "featureName": "Kanban",
                            "featureDesc": "Kanban",
                            "membershipPlan": {
                                "planId": 1,
                                "orgId": "101",
                                "planName": "GOLD",
                                "planPrice": "29",
                                "planFeature": [... and so on

below is the exception:

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)]

Please let me know where I am doing it wrong.


Solution

  • You have to tell Jackson to skip generate nested fields to your entities:

        ...
        @ManyToOne
        @JoinColumn(name = "plan_id")
        @JsonBackReference // Add this
        private MembershipPlan membershipPlan;
        ...
    
        ...
        @OneToMany(mappedBy = "membershipPlan")
        @JsonManagedReference // Add this
        private List<MembershipPlanFeature> planFeature;
        ...