-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Unidirectional one-to-many relationship
PostPosted: Wed Mar 11, 2009 12:09 am 
Beginner
Beginner

Joined: Tue Mar 10, 2009 11:50 pm
Posts: 23
Parent {
Parent_Id;
Name;
Desc;
}


Child {
Child_Id;
Name
Parent_Id (not-null)
}


@Entity
public class Parent implements Serializable {

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="PARENT_ID")
public Set<Child> getChilds() {
...
}

@Entity
public class Child implements Serializable {
... //no bidir
}

I dont want Child to have reference of parent, but hibernate seems to be not identifying the parent of child by the virtue of mapping in parent and inserting into parent_id foreign key of child.

The only alternative is have Parent_Id attribute in Child class and make Parent_Id as nullable in database. But having nullable foreign key is not a best data practice as per our DB administrator.

Our java architect does not want to have circular bi-directional reference, as its not best practice in java.

Please suggest any alternative


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 12:30 am 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
Vinu wrote:
I dont want Child to have reference of parent, but hibernate seems to be not identifying the parent of child by the virtue of mapping in parent and inserting into parent_id foreign key of child.

What makes you think like this?

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 12:48 am 
Beginner
Beginner

Joined: Tue Mar 10, 2009 11:50 pm
Posts: 23
I am referring to

Not-Null Constraint-Violation with unidirectional one-to-many mapping

Please refer
http://opensource.atlassian.com/project ... e/HHH-2280


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 2:08 am 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
That issue talks about association using a join table. But i think in ur case its jst a foreign key column in Child table. So you can have nullable=false in the @JoinColumn annotation and hibernate will take care of that. No need for reference to Parent from Child.

Code:
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "PARENT_ID", nullable = false)
   public Set<Child> getChildren() {
      ......
   }

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 3:40 am 
Beginner
Beginner

Joined: Tue Mar 10, 2009 11:50 pm
Posts: 23
Thanks littypreethkr,

It worked !! the magic done by nullable = false on the @JoinColumn.

Now i can have not-null constraint on my DB pleasing my DBA :)


Top
 Profile  
 
 Post subject: Hibernate annotations documentation needs to be update
PostPosted: Wed Mar 11, 2009 5:00 am 
Beginner
Beginner

Joined: Tue Mar 10, 2009 11:50 pm
Posts: 23
I think w.r.t to the above solution, hibernate documentation needs to be updated when they are explaining about unidirectional

it should be @JoinColumn(name="CUST_ID" , nullable = false)

2.2.5.3.2.2. Unidirectional

A unidirectional one to many using a foreign key column in the owned entity is not that common and not really recommended. We strongly advise you to use a join table for this kind of association (as explained in the next section). This kind of association is described through a @JoinColumn

@Entity
public class Customer implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
public Set<Ticket> getTickets() {
...
}

@Entity
public class Ticket implements Serializable {
... //no bidir
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 11, 2009 5:10 am 
Expert
Expert

Joined: Fri Jan 30, 2009 1:47 am
Posts: 292
Location: Bangalore, India
Quote:
it should be @JoinColumn(name="CUST_ID" , nullable = false)

Not really. nullable=false is required only for non-null foreign key column.

Usually if you specify cascade for a one-to-many relation then hibernate first creates the child objects (with null value in foreign key column), then the parent and then updates the child row's foreign key column with parent's id. (This will cause a constraint violation if the foreign key column is non-null)

But if the nullable=false is specified, then first the parent row is created and then child row is created withe the foreign key of the parent and this will solve the constraint violation error. (I dont know why hibernate doesn't do like this in the nullable=true case also so that this special case can be avoided.)

_________________
Regards,
Litty Preeth


Top
 Profile  
 
 Post subject: Re: Unidirectional one-to-many relationship
PostPosted: Tue Mar 23, 2010 9:55 pm 
Newbie

Joined: Tue Mar 23, 2010 9:38 pm
Posts: 1
Actually I also solved my problem using nullable=false, but I don't get the behavior you described when setting nullable to true, ie. I don't get the last update that should occur:
//Customer Entity
package un.fold;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;

@Entity
public class Customer {
private int id;
private String name;
private Set<OrderItem> orders = new HashSet<OrderItem>();

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="customer_id")
public Set<OrderItem> getOrders() {
return orders;
}

public void setOrders(Set<OrderItem> newValue) {
this.orders = newValue;
}

public void addOrderItem(OrderItem orderItem) {
orders.add(orderItem);
}
}

//OrderItem Entity
@Entity
public class OrderItem {
private int id;
private String address;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

//simple test case
Customer customer = new Customer();
customer.setName("RAMAR");

OrderItem order1 = new OrderItem();
order1.setAddress("MOON");

OrderItem order2 = new OrderItem();
order2.setAddress("EARTH");

customer.addOrderItem(order1);
customer.addOrderItem(order2);

storeService.saveCustomer(customer);

When the snippet above runs, the customer_id column is set to NULL for both OrderItem entries, but when I set nullable to false, they hold the customer_id value.

This is the SQL output:
Hibernate:
insert
into
Customer
(id, name)
values
(null, ?)
Hibernate:
call identity()
Hibernate:
insert
into
OrderItem
(id, address, orders_id)
values
(null, ?, ?)
Hibernate:
call identity()
Hibernate:
insert
into
OrderItem
(id, address, orders_id)
values
(null, ?, ?)
Hibernate:
call identity()

All in all this is really strange, because it is at odds with what you describe, as the ultimate update statement is nowhere to be seen.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.