I'm trying to join 2 tables (ManytoMany) and I'm getting this error:
Caused by: org.hibernate.AnnotationException: referencedColumnNames(planDate, planId, weekday) of com.MD.Medicine.Models.Meds.assignedMeds referencing com.MD.Medicine.Models.Plans not mapped to a single property
My entities, Plans.java:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "plans")
@EqualsAndHashCode(exclude = "assignedMeds")
public class Plans {
@EmbeddedId
private PlansPKId plansPKId;
@Column
private String planName;
@Column
private String weekday;
@ManyToMany
@JoinTable(name = "Plan_Meds", joinColumns = {
@JoinColumn(name = "planDate", referencedColumnName = "planDate"),
@JoinColumn(name = "planId", referencedColumnName = "planId"),
@JoinColumn(name = "weekday", referencedColumnName = "weekday"), }, inverseJoinColumns = @JoinColumn(name = "id"))
private Set<Meds> assignedMeds = new HashSet<>();
}
PlansPKId.java (for Plans Model):
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
public class PlansPKId implements Serializable {
private Date planDate; // format: yyyy-mm-dd
private long planId;
}
Meds.java:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "meds")
public class Meds {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column
private String name;
@Column
private BigDecimal price;
@Column
private String category;
@Column
private int pillNumber;
@Column
private Date date;
@JsonIgnore
@ManyToMany(mappedBy = "assignedMeds")
private Set<Plans> plans = new HashSet<>();
}
When I join only with this:
@ManyToMany
@JoinTable(name = "Plan_Meds", joinColumns = {
@JoinColumn(name = "planDate", referencedColumnName = "planDate"),
@JoinColumn(name = "planId", referencedColumnName = "planId"), },
inverseJoinColumns = @JoinColumn(name = "id"))
private Set<Meds> assignedMeds = new HashSet<>();
It works properly, but if I had the column "weekday" I start getting the error. Am I not supposed to join them like that?
CodePudding user response:
Yes, basically, the purpose of @JoinTable
is to create an intermediate table that only contains keys of each participant table.
@ManyToMany
@JoinTable(name = "Plan_Meds", joinColumns = {
@JoinColumn(name = "planDate", referencedColumnName = "planDate"),
@JoinColumn(name = "planId", referencedColumnName = "planId"),
@JoinColumn(name = "weekday", referencedColumnName = "weekday"), }, inverseJoinColumns = @JoinColumn(name = "id"))
private Set<Meds> assignedMeds = new HashSet<>();
In this case,
joinColumns = {
@JoinColumn(name = "planDate", referencedColumnName = "planDate"),
@JoinColumn(name = "planId", referencedColumnName = "planId")}
will refer to the key of your Plans
entity plansPKId, and
inverseJoinColumns = @JoinColumn(name = "id")
will refer to the Meds
entity's key id. Since weekday @JoinColumn(name = "weekday", referencedColumnName = "weekday")
, it's not referring to any key, it should not be here.
In case you need to add some more fields in the join table, manually create your own join table and use @ManyToOne instead: manytomany