Search code examples
javahibernatehibernate-mappinghibernate-annotationshibernate-cascade

Hibernate Cascade another Id from another database


For Example, I have class A with cascade to B:

public class A{

    private String id;
    private Set<B> bs = new HashSet<B>(0);

    @Id
    @GenericGenerator(name = "seq_id", strategy = generators.SequenceIdGenerator")
    @GeneratedValue(generator = "seq_id")
    @COLUMN(name="id" unique = true, nullable = false, length = 28)
    public void getId(){
        return this.id;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "A")
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE, CascadeType.PERSIST})
    public void getBs(){
        return bs;
    }
}

and I have B which has it's own id and a column containing id from A

public class B

    String id; 
    String aId;
    A a;

    @Id
    @GenericGenerator(name = "seq_id", strategy = "generators.SequenceIdGenerator")
    @GeneratedValue(generator = "seq_id")
    @Column(name = "ID", unique = true, nullable = false, length = 28)
    public String getId() {
        return this.id;
    }

    @Column(name = "A_ID", nullable = false, length = 28)
    public String getAId() {
        return aId;
    }

    public void setAId(String aId) {
         this.aId = aId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "A_ID", nullable = false, insertable = false, updatable = false)
    @MapsId("aId")
    public Admission getAdmission() {
        return this.admission;
    }

    public void setAdmission(Admission admission) {
    this.admission = admission;
    }

how do I assign aId automatically upon saving A? I want aId to be set but I always get an error which says that A_ID can't be set to null.

Thanks!


Solution

  • When using derived identifier with shared mappings, you need not only to put the @MapsId anotation in the relationship but to anotate the field referencing the relationship id with the @Id annotation.

    See how to do it (setters ommited):

    public class B {
        String id;
        String aId;
        A a;
    
        @Id
        @GenericGenerator(name = "seq_id", strategy = "generators.SequenceIdGenerator")
        @GeneratedValue(generator = "seq_id")
        @Column(name = "ID", unique = true, nullable = false, length = 28)
        public String getId() {
            return this.id;
        }
    
        @Id
        public String getAId() {
            return aId;
        }
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "A_ID", nullable = false)
        @MapsId("aId")
        public A getA() {
            return this.a;
        }
    }
    

    The other mistake is that you annotated your relationship to be updatable = false and insertable = false, making the persistence provider ignore the writing of this field to the database.