Reputation: 292
I have 2 classes called PurchaseList.java and PurchaseListItems.java
I have to map PurchaseList in PurchaseListItems
PurchaseList.java
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;
PurchaseListItems.java
@ManyToOne
@JoinColumn(name="pl_id")
private PurchaseList purchaseListId;
Everything is fine but i am getting null in pl_id. Please tell where i am wrong
Upvotes: 15
Views: 32878
Reputation: 1014
For some reason mapped by didn't work for me with postgres sql and Hibernate4
Below mapping worked
PurchaseList.java
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="pl_id",nullable=false)
private List<PurchaseListItems> purchaseListItems;
PurchaseListItems.java
@ManyToOne
@JoinColumn(name="pl_id", nullable=false,insertable=false,updatable=false )
private PurchaseList purchaseListId;
Note: you have to use the Identity or Explicitly mention the Sequence for id columns for postgres.
@GeneratedValue(strategy=GenerationType.IDENTITY)
Upvotes: 8
Reputation: 2122
Your mapping actually defines two independent unidirectional relations. What you want is one bidirectional relation.The following code will establish the bidirectional relation
@OneToMany(cascade = CascadeType.ALL, mappedBy = "purchaseListId")
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;
The mappedBy attribute is necessary since there is no way for the provider to automatically determine that the specified relations actually form a single relation. One could use the Java type of the instance member but then what if you have multiple members of the same type. And there are many scenarios where you have two single relations. Example:
OneToMany: User -> ForumThread (the threads created by the user)
ManyToOne: ForumThread -> User (the user who closed the thread. obviously not necessarily the one who started the thread)
These are two independent relations and must be treated as such. You would be quite surprised if your persistence provide just made a bidirectional relation out of that just because the types and multiplicity matched.
Also note that bidirectional relations are not automatically managed by any JPA provider, meaning that the inverse side is not automatically updated/set in your object model and thus not in the db. You have to do that yourself. By the way, in all my projects bidirectional relationships were a pain in the ass and I think it is advisable to avoid them.
Upvotes: 6
Reputation: 23115
The @JoinColumn annotation belongs on the @ManyToOne side of the relationship - but not on the @OneToMany side - remove it from the @OneToMany side.
Cascade is used to cascade DELETE/READ/UPDATE operations..., but it does not automatically populate the ID column on the "child" side of a foreign key. In fact, it doesn't populate the java references to objects on either side of the FK relationship. You need to manually setup relationship data on both sides of bidirectional relationships:
myPurchaseListItem.setPurchaseList(myPurchaseList);
myPurchaseList.setPurchaseListItem(myPurchaseListItem);
From the JPA 2 spec:
Bidirectional relationships between managed entities will be persisted based on references held by the owning side of the relationship. It is the developer’s responsibility to keep the in-memory references held on the owning side and those held on the inverse side consistent with each other when they change. In the case of unidirectional one-to-one and one-to-many relationships, it is the developer’s responsibility to insure (sic) that the semantics of the relationships are adhered to.[29]
It is particularly important to ensure that changes to the inverse side of a relationship result in appropriate updates on the owning side, so as to ensure the changes are not lost when they are synchronized to the database.
Upvotes: 2
Reputation: 292
for(PurchaseListItems item:purchaseListItemsList)
item.purchaseListId(PurchaseList);
This is what I missed when i am creating an object.
Thnaks for your answers
Upvotes: 1
Reputation: 2274
Check if you have populated purchaseListId with valid value (a created PurchaseList instance) when you create a PurchaseListItems value.
It's better to use mappedBy as below code to let many-side to maintian the relationship.
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId")
@JoinColumn(name="pl_id",referencedColumnName="id")
private List<PurchaseListItems> purchaseListItems;
Upvotes: 0
Reputation: 40358
try this
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "purchaseListId")
Upvotes: 0
Reputation: 1072
The jpa specification looks good, but verify you have given valid parent to child relationship in the database. If there is not a reference then it will return null.
Upvotes: 0