Search code examples
hibernatejpamergecomposite-id

Hibernate composite id merge


I'm using Hibernate with JPA and have a relation like this:

@Entity
@Table(name = "first")
public class First {
...
@OneToMany(mappedBy = "first")
private List<Availability> availabilities;
...
}


@Entity
@Table(name = "second")
public class Second {
...
@OneToMany(mappedBy = "second")
private List<Availability> availabilities;
...
}

@Entity
@Table(name="availability")
public class Availability implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "first_id")
private First first;

@Id
@ManyToOne
@JoinColumn(name = "second_id")
private Second second;

@Column(name = "availability")
private Integer availability;

...
hashcode and equals
}

I want to manage these 3 entities separately. First and Second work fine, but when I try to merge() the third one postgresql gets a null value instead of the id's and constraint violation exception is thrown. Why? Can I even use merge on this entity to add new rows to the table?

update: The merge is something like this:

public Availability setAvailability(Availability a) {
return em.merge(a);
}

where the availability is deserialized from front-end (just to mention, the collections of "key" classes are detached in it).


Solution

  • I solved the problem by avoiding the use of Composite ID. After rethinking the problem I found out that this case I actually can use an unique constraint.

    @Entity
    @Table(name = "availabilities", uniqueConstraints = { @UniqueConstraint(columnNames = {
        "first_id", "second_id" }) })
    @SequenceGenerator(initialValue = 1, name = "availabilities_sequence", sequenceName =     "availabilities_sequence")
    public class Availability implements IAvailability, Serializable {
    
    private static final long serialVersionUID = -2977047920673617888L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "availabilities_sequence")
    @Column(name = "id")
    private Integer id;
    
    @ManyToOne
    @JoinColumn(name = "first_id", nullable=false)
    private First first;
    
    @ManyToOne
    @JoinColumn(name = "second_id", nullable=false)
    private Second second;
    
    @Column(name = "availability", nullable=false)
    private Integer availability;
    
    ...
    }