8

I have a general question about Hibernate that I'm batteling with.

I have class A and class B, where B is dependent on A

In my code when I call em.persist(objOfTypeA) I would expect the insert to go and insert into both tables AAA and BBB. If I manually presist A get A's ID and fill it in the list for each object and then persist that list, things are working. But I would expect this to happen magically by Hibernate.

Am I doing something wrong? Or am I just expecting too much of Hibernate?

Thanks

@Entity
@Table(name = "AAA")
@Veto
public class A {

    @Id
    @GeneratedValue
    @Column(name = "Id")
    private Long id;


    @NotNull
    @Column(name = "Name")
    private Long name;

    ...

    @OneToMany(mappedBy="a", fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    private List<B> b;
...
}

@Entity
@Table(name = "BBB")
@Veto
public class B {

    @Id
    @GeneratedValue
    @Column(name="Id")
    private Long id;

    @NotNull
    @Column(name="AId")
    private Long aId;

    @NotNull
    @Column(name = "Name")
    private Long name;

    @JoinColumn(name = "AId", referencedColumnName="Id", updatable = false, insertable = false)
    @ManyToOne(optional = false)
    private A a;
...     
}
WonkeyDonkey
  • 119
  • 1
  • 1
  • 5

2 Answers2

3

I finally worked it out. None of the examples I was given or found told me exactly what was wrong, it was only after my own experimentation that I managed to come to this conclusion:

Instead of having

@OneToMany(mappedBy="a", fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
private List<B> b;

that didn't work (FK was still coming as NULL)

This did work:

@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name="AId")
@NotNull
private List<B> b;
pants
  • 192
  • 13
WonkeyDonkey
  • 119
  • 1
  • 1
  • 5
  • This didn't work for me. The problem is that Hibernate wants the A to be set on the B before persisting. This worked: http://stackoverflow.com/questions/1795649/jpa-persisting-a-one-to-many-relationship –  Jan 11 '16 at 03:48
1

Modify the mapping of class B as below,

@Entity
@Table(name = "BBB")
@Veto
public class B {

    @Id
    @GeneratedValue
    @Column(name="Id")
    private Long id;

    @NotNull
    @Column(name="AId", updatable = false, insertable = false)
    private Long aId;

    @NotNull
    @Column(name = "Name")
    private Long name;

    @JoinColumn(name = "AId", referencedColumnName="Id")
    @ManyToOne(optional = false)
    private A a;
...     
}

You were using the attributes updatable = false, insertable = false at wrong place and I have corrected it.

Read here to understand how they works.

Community
  • 1
  • 1
ManuPK
  • 11,623
  • 10
  • 57
  • 76
  • Hi ManuPK, Thanks for your answer, but this didn't solve my problem. While trying to persist (A) I am getting an error that aId for B is null. ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=aId, rootBeanClass=class com.test.model.B, messageTemplate='{javax.validation.constraints.NotNull.message}'} I am not sure if on the SQL Server side I have to have both id's (A's and B's) as identity or will Hibernate take care of that? But I am assuming that's ok as it's not complaining for that it's complaining on the FK. – WonkeyDonkey Feb 26 '12 at 12:44
  • DB is looking like this: Table1: AAA Id bigint not null, Name varchar(100) Table2: BBB Id bigint not null, AId bigint not null, Name varchar(100) Thanks! – WonkeyDonkey Feb 26 '12 at 12:44
  • I went back to the DB and removed 'not null' from AId and also the @NotNull from aId in B class. Now the persist is successful But when I look at the DB. AAA is all good, but BBB is missing the AId. Help.. – WonkeyDonkey Feb 26 '12 at 13:01
  • Follow this [example](http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/) to create the classes. – ManuPK Feb 27 '12 at 02:43