Home > Blockchain >  Jpa, linked class take main class id
Jpa, linked class take main class id

Time:07-26

I have a Product :

@Data
@Entity
@Table(name = "products", schema = "laboratory", catalog = "laboratory")
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Product {
    @Id
    @GeneratedValue
    private int id;
    @ManyToOne(fetch = FetchType.LAZY, cascade= CascadeType.ALL)
    @JoinColumn(name = "project_id")
    @Transient
    private Project project; // this one is for read only
    @Column(name="project_id") // this will save the id in db for the project
    private int projectId;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="id")
    private Inspection inspection;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="id")
    private Information information;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="id")
    private Departure departure;
    private String un;
    private String tc;
}

There is 3 class that this product needs in order to be a Product : Information, Inpection, Departure

All 3 of these classes are similar. I want to link them by the Product.id witch is a @GeneratedValue AI in sql.

Here is one of the 3 class : Information

@Data
@Entity
@Table(name = "products_informations", schema = "laboratory", catalog = "laboratory")
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Information {
    @Id
    private int productId;
    private String description;
    private String model;
    private int year;
    private String serialNumber;
    private int odometre;
    private int noCrochet;
    private int nbKeys;
    private String localisation;
    private String cemeteryPosition;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date receptionDate;
}

I want, WHEN I save() the product, that the private String productId in this class to automatically take the Id from the Product class without having to do it manually in my controller.

CodePudding user response:

You have the mappings backwards in your model.

By using

public class Product {
    @Id
    @GeneratedValue
    private int id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="id")
    private Information information;

You've told JPA to use the PRODUCT.ID primary key as a foreign key to the Information table; foreign keys are controlled by the relationship, so it means your ID value is pulled from the information.productId value. Opposite of what you are asking for and it means you have 4 mappings trying to set the PRODUCT.ID column value (set them different and see for yourself).

Try this instead:

public class Product {
    @Id
    @GeneratedValue
    private int id;

    @OneToOne(mappedby="product", cascade = CascadeType.ALL)
    private Information information;
    ..
}

public class Information {
    @Id
    private int productId;
    @MapsId
    private Product product;
    ..
}

With this you will need to set the Information.product reference, but JPA will use that to set your productId value, using the one you set within the product.id property. You just need to set this relationship when you add an Information instance to a product. Do the same for the other relationships

  • Related