Hibernate JPA IdentifierGenerationException: null id generated for class with @embeddedid
I am having problems mapping my database domain model to programmatic entities in one case where the entity is essentially a join table (period) that joins two other objects (time interval and day). Another object (lesson) then has a reference to an object from that period that determines when it occurs.
When I try to save the lesson with a new period using saveOrUpdate(lesson)
hibernate throws an IdentifierGenerationException
org.hibernate.id.IdentifierGenerationException: null id is generated for: class com.trials.domain.Period
The database looks like below (not a real database, just key tables and columns)
In the java hibernate model, I used the built-in id for the primary key of the period class and the lesson class then references the period.
Period.java
@Entity
@Table(name = "period")
public class Period{
@EmbeddedId
private PeriodId periodId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "day_idday", nullable = false, insertable = false, updatable = false)
private Day day;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "timeslot_idtimeslot", nullable = false, insertable = false, updatable = false)
private Timeslot timeslot;
//constructors, getters, setters, hashcode, and equals
}
And the built-in ID only has primary key columns:
PeriodId.java
@Embeddable
public class PeriodId implements Serializable {
@Column(name = "timeslot_idtimeslot")
private int timeslotId;
@Column(name = "day_idday")
private int dayId;
//constructors, getters, setters, hashcode, and equals
}
Then there is a lesson class that uses a period defined as:
Lesson.java
@Entity
@Table(name = "lesson")
public class Lesson {
@Id
@Column(name = "idlesson")
private int lessonId;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumns({@JoinColumn(name = "period_timeslot_idtimeslot", nullable = false, updatable = false), @JoinColumn(name = "period_day_idday", nullable = false, updatable = false)})
private Period period;
//constructors, getters, setters, hashcode, and equals
}
The Timeslot and Day entity classes are very basic pojos and their IDs are used GenerationType.AUTO
. So my problems are:
- What is causing this IdentifierGenerationException
- How to avoid this while maintaining the same database model
Thank you in advance
source to share
Put these guys
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "day_idday", nullable = false, insertable = false, updatable = false)
private Day day;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "timeslot_idtimeslot", nullable = false, insertable = false, updatable = false)
private Timeslot timeslot;
inside the PeriodId class and throw away those ints. I made a mapping like yours and it works.
source to share
I was able to create the following mapping for my case (scala code) and exclude the @Embeddable class entirely:
@Entity
@Table(name = "payment_order_item", schema = "pg")
@IdClass(classOf[PaymentOrderItem])
final class PaymentOrderItem extends Serializable{
@Id
@ManyToOne
@JoinColumn(name = "order_item_id", referencedColumnName = "id")
var orderItem: OrderItem = _
@Id
@ManyToOne
@JoinColumn(name = "payment_id", referencedColumnName = "id")
var payment: Payment = _
}
So the following should work for you:
@Entity
@Table(name = "period")
@IdClass(Period.class)
public class Period extends Serializable{
@Id
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "day_idday", referencedColumnName = "id", nullable = false)
private Day day;
@Id
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "timeslot_idtimeslot", referencedColumnName = "id", nullable = false)
private Timeslot timeslot;
//constructors, getters, setters, hashcode, and equals
}
source to share
At first glance, you are missing the generated value annotation in the built-in id class.
@Embeddable
public class PeriodId implements Serializable {
@GeneratedValue
@Column(name = "timeslot_idtimeslot")
private int timeslotId;
@GeneratedValue
@Column(name = "day_idday")
private int dayId;
//constructors, getters, setters, hashcode, and equals
}
source to share