HHH-4685 Make sure bidirectional @*To* works from an embedded object to another entity

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18543 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Scott Marlow 2010-01-13 19:35:54 +00:00
parent e8df1d1579
commit 9256bc30e5
6 changed files with 221 additions and 1 deletions

View File

@ -0,0 +1,24 @@
package org.hibernate.test.annotations.manytomany;
import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.ManyToMany;
import java.util.List;
@Embeddable
public class ContactInfo {
// @ManyToOne
// Address address; // Unidirectional
List<PhoneNumber> phoneNumbers; // Bidirectional
@ManyToMany(cascade= CascadeType.ALL)
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
}

View File

@ -4,6 +4,7 @@ package org.hibernate.test.annotations.manytomany;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@ -26,6 +27,29 @@ public class Employee implements Serializable {
private Integer id;
private Collection<Employer> employers;
private String name;
ContactInfo contactInfo;
JobInfo jobInfo;
// ContactInfo is for ManyToMany testing
@Embedded
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
// JobInfo is for OneToMany testing
@Embedded
public JobInfo getJobInfo() {
return jobInfo;
}
public void setJobInfo(JobInfo jobInfo) {
this.jobInfo = jobInfo;
}
@Column(name="fld_name")
public String getName() {

View File

@ -0,0 +1,29 @@
package org.hibernate.test.annotations.manytomany;
import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
@Embeddable
public class JobInfo {
String jobDescription;
ProgramManager pm; // Bidirectional
public String getJobDescription() {
return jobDescription;
}
public void setJobDescription( String jobDescription ) {
this.jobDescription = jobDescription;
}
@ManyToOne( cascade= CascadeType.ALL)
public ProgramManager getPm() {
return pm;
}
public void setPm( ProgramManager pm ) {
this.pm = pm;
}
}

View File

@ -1,4 +1,5 @@
//$Id$
//$Id$
package org.hibernate.test.annotations.manytomany;
@ -7,6 +8,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Hibernate;
@ -641,6 +643,81 @@ public class ManyToManyTest extends TestCase {
s.close();
}
// Test for HHH-4685
// Section 11.1.25
// The ManyToMany annotation may be used within an embeddable class contained within an entity class to specify a
// relationship to a collection of entities[101]. If the relationship is bidirectional and the entity containing
// the embeddable class is the owner of the relationship, the non-owning side must use the mappedBy element of the
// ManyToMany annotation to specify the relationship field or property of the embeddable class. The dot (".")
// notation syntax must be used in the mappedBy element to indicate the relationship attribute within the embedded
// attribute. The value of each identifier used with the dot notation is the name of the respective embedded field
// or property.
public void testManyToManyEmbeddableBiDirectionalDotNotationInMappedBy() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Employee e = new Employee();
e.setName( "Sharon" );
List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
Collection<Employee> employees = new ArrayList<Employee>();
employees.add( e );
ContactInfo contactInfo = new ContactInfo();
PhoneNumber number = new PhoneNumber();
number.setEmployees( employees );
phoneNumbers.add( number );
contactInfo.setPhoneNumbers( phoneNumbers );
e.setContactInfo( contactInfo );
s.persist( e );
s.flush();
s.clear();
tx.commit();
tx.begin();
e = (Employee)s.get( e.getClass(),e.getId() );
// follow both directions of many to many association
assertEquals("same employee", e.getName(), e.getContactInfo().getPhoneNumbers().get(0).getEmployees().iterator().next().getName());
tx.commit();
s.close();
}
// Test for HHH-4685
// Section 11.1.26
// The ManyToOne annotation may be used within an embeddable class to specify a relationship from the embeddable
// class to an entity class. If the relationship is bidirectional, the non-owning OneToMany entity side must use the
// mappedBy element of the OneToMany annotation to specify the relationship field or property of the embeddable field
// or property on the owning side of the relationship. The dot (".") notation syntax must be used in the mappedBy
// element to indicate the relationship attribute within the embedded attribute. The value of each identifier used
// with the dot notation is the name of the respective embedded field or property.
public void testOneToManyEmbeddableBiDirectionalDotNotationInMappedBy() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Employee e = new Employee();
JobInfo job = new JobInfo();
job.setJobDescription( "Sushi Chef" );
ProgramManager pm = new ProgramManager();
Collection<Employee> employees = new ArrayList<Employee>();
employees.add(e);
pm.setManages( employees );
job.setPm(pm);
e.setJobInfo( job );
s.persist( e );
s.flush();
s.clear();
tx.commit();
tx.begin();
e = (Employee) s.get( e.getClass(), e.getId() );
assertEquals( "same job in both directions",
e.getJobInfo().getJobDescription(),
e.getJobInfo().getPm().getManages().iterator().next().getJobInfo().getJobDescription() );
tx.commit();
s.close();
}
/**
* @see org.hibernate.test.annotations.TestCase#getMappings()
*/
@ -664,7 +741,9 @@ public class ManyToManyTest extends TestCase {
Inspector.class,
InspectorPrefixes.class,
BuildingCompany.class,
Building.class
Building.class,
PhoneNumber.class,
ProgramManager.class
};
}

View File

@ -0,0 +1,31 @@
package org.hibernate.test.annotations.manytomany;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.Collection;
@Entity
public class PhoneNumber {
int phNumber;
Collection<Employee> employees;
@Id
public int getPhNumber() {
return phNumber;
}
public void setPhNumber(int phNumber) {
this.phNumber = phNumber;
}
@ManyToMany(mappedBy="contactInfo.phoneNumbers", cascade= CascadeType.ALL)
public Collection<Employee> getEmployees() {
return employees;
}
public void setEmployees(Collection<Employee> employees) {
this.employees = employees;
}
}

View File

@ -0,0 +1,33 @@
package org.hibernate.test.annotations.manytomany;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.Collection;
@Entity
public class ProgramManager {
int id;
Collection<Employee> manages;
@Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@OneToMany( mappedBy="jobInfo.pm", cascade= CascadeType.ALL )
public Collection<Employee> getManages() {
return manages;
}
public void setManages( Collection<Employee> manages ) {
this.manages = manages;
}
}