HHH-9387 HHH-9389 : Default collection table and join column names generated for @ElementCollection (test cases)
HHH-9387 HHH-9389 : Default collection join column names generated for @ElementCollection (test cases)
(cherry picked from commit f2ae61abf6
)
Conflicts:
hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/CollectionElementTest.java
hibernate-core/src/test/java/org/hibernate/test/annotations/collectionelement/Matrix.java
This commit is contained in:
parent
00c2788d2b
commit
e4b0915a8e
|
@ -37,10 +37,10 @@ import org.hibernate.Session;
|
|||
import org.hibernate.Transaction;
|
||||
import org.hibernate.metamodel.spi.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.spi.binding.PluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.test.annotations.Country;
|
||||
import org.hibernate.test.util.SchemaUtil;
|
||||
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
@ -64,8 +64,8 @@ public class CollectionElementTest extends BaseCoreFunctionalTestCase {
|
|||
boy.setLastName( "Doe" );
|
||||
boy.getNickNames().add( "Johnny" );
|
||||
boy.getNickNames().add( "Thing" );
|
||||
boy.getScorePerNickName().put( "Johnny", Integer.valueOf( 3 ) );
|
||||
boy.getScorePerNickName().put( "Thing", Integer.valueOf( 5 ) );
|
||||
boy.getScorePerNickName().put( "Johnny", 3 );
|
||||
boy.getScorePerNickName().put( "Thing", 5 );
|
||||
int[] favNbrs = new int[4];
|
||||
for (int index = 0; index < favNbrs.length - 1; index++) {
|
||||
favNbrs[index] = index * 3;
|
||||
|
@ -174,8 +174,8 @@ public class CollectionElementTest extends BaseCoreFunctionalTestCase {
|
|||
boy.setLastName( "Doe" );
|
||||
boy.getNickNames().add( "Johnny" );
|
||||
boy.getNickNames().add( "Thing" );
|
||||
boy.getScorePerNickName().put( "Johnny", new Integer( 3 ) );
|
||||
boy.getScorePerNickName().put( "Thing", new Integer( 5 ) );
|
||||
boy.getScorePerNickName().put( "Johnny", 3 );
|
||||
boy.getScorePerNickName().put( "Thing", 5 );
|
||||
int[] favNbrs = new int[4];
|
||||
for (int index = 0; index < favNbrs.length - 1; index++) {
|
||||
favNbrs[index] = index * 3;
|
||||
|
@ -257,24 +257,6 @@ public class CollectionElementTest extends BaseCoreFunctionalTestCase {
|
|||
isDefaultValueCollectionColumnPresent( Boy.class.getName(), "scorePerPreferredName");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultFKNameForElementCollection() throws Exception {
|
||||
isCollectionColumnPresent( Boy.class.getName(), "hatedNames", "Boy_id" );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@FailureExpectedWithNewMetamodel( jiraKey = "HHH-9281" )
|
||||
@TestForIssue( jiraKey = "HHH-9281")
|
||||
public void testDefaultTableNameUsesJpaEntityName() {
|
||||
final TableSpecification table = getCollectionTable( Matrix.class.getName(), "mvalues");
|
||||
assertEquals( "Mtx_mvalues", table.getLogicalName().getText() );
|
||||
}
|
||||
|
||||
private void isLegacyValueCollectionColumnPresent(String collectionHolder, String propertyName) {
|
||||
|
||||
}
|
||||
|
||||
private void isDefaultValueCollectionColumnPresent(String collectionOwner, String propertyName) {
|
||||
isCollectionColumnPresent( collectionOwner, propertyName, propertyName );
|
||||
}
|
||||
|
@ -286,12 +268,133 @@ public class CollectionElementTest extends BaseCoreFunctionalTestCase {
|
|||
assertTrue( "Could not find " + columnName, hasColumn );
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9387")
|
||||
public void testDefaultTableNameNoOverrides() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Products has @Entity (no @Table)
|
||||
checkDefaultCollectionTableName( BugSystem.class, "bugs", "BugSystem_bugs" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9387")
|
||||
public void testDefaultTableNameOwnerPrimaryTableOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Boy has @Entity @Table(name="tbl_Boys")
|
||||
checkDefaultCollectionTableName( Boy.class, "hatedNames", "Boy_hatedNames" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9387")
|
||||
@FailureExpected( jiraKey = "HHH-9387")
|
||||
public void testDefaultTableNameOwnerEntityNameAndPKColumnOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Matrix has @Entity(name="Mtx"); entity table name defaults to "Mtx"; owner PK column is configured as "mId"
|
||||
checkDefaultCollectionTableName( Matrix.class, "mvalues", "Mtx_mvalues" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9387")
|
||||
@FailureExpected( jiraKey = "HHH-9387")
|
||||
public void testDefaultTableNameOwnerPrimaryTableAndEntityNamesOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
|
||||
// Owner has @Entity( name="OWNER") @Table( name="OWNER_TABLE")
|
||||
checkDefaultCollectionTableName( Owner.class, "elements", "OWNER_elements" );
|
||||
}
|
||||
|
||||
private void checkDefaultCollectionTableName(
|
||||
Class<?> ownerEntityClass,
|
||||
String ownerCollectionPropertyName,
|
||||
String expectedCollectionTableName) {
|
||||
final TableSpecification table =
|
||||
getCollectionTable( ownerEntityClass.getName(), ownerCollectionPropertyName );
|
||||
assertEquals( expectedCollectionTableName, table.getLogicalName().getText() );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9389")
|
||||
public void testDefaultJoinColumnNoOverrides() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Products has @Entity (no @Table)
|
||||
checkDefaultJoinColumnName( BugSystem.class, "bugs", "BugSystem_id" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9389")
|
||||
@FailureExpected( jiraKey = "HHH-9389")
|
||||
public void testDefaultJoinColumnOwnerPrimaryTableOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Boy has @Entity @Table(name="tbl_Boys")
|
||||
checkDefaultJoinColumnName( Boy.class, "hatedNames", "Boy_id" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9389")
|
||||
public void testDefaultJoinColumnOwnerEntityNameAndPKColumnOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
// Matrix has @Entity(name="Mtx"); entity table name defaults to "Mtx"; owner PK column is configured as "mId"
|
||||
checkDefaultJoinColumnName( Matrix.class, "mvalues", "Mtx_mId" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9389")
|
||||
@FailureExpected( jiraKey = "HHH-9389")
|
||||
public void testDefaultJoinColumnOwnerPrimaryTableAndEntityNamesOverride() {
|
||||
// NOTE: expected JPA entity names are explicit here (rather than just getting them from the PersistentClass)
|
||||
// to ensure that entity names/tables are not changed (which would invalidate these test cases).
|
||||
|
||||
|
||||
// Owner has @Entity( name="OWNER") @Table( name="OWNER_TABLE")
|
||||
checkDefaultJoinColumnName( Owner.class, "elements", "OWNER_id" );
|
||||
}
|
||||
|
||||
private void checkDefaultJoinColumnName(
|
||||
Class<?> ownerEntityClass,
|
||||
String ownerCollectionPropertyName,
|
||||
String ownerForeignKeyNameExpected) {
|
||||
final EntityBinding entityBinding = metadata().getEntityBinding( ownerEntityClass.getName() );
|
||||
// The default owner join column can only be computed if it has a PK with 1 column.
|
||||
assertEquals(
|
||||
1,
|
||||
entityBinding.getHierarchyDetails()
|
||||
.getEntityIdentifier()
|
||||
.getEntityIdentifierBinding()
|
||||
.getRelationalValueBindings()
|
||||
.size()
|
||||
);
|
||||
|
||||
final ForeignKey ownerForeignKey = getCollectionForeignKey( ownerEntityClass.getName(), ownerCollectionPropertyName );
|
||||
assertEquals( ownerForeignKeyNameExpected, ownerForeignKey.getColumns().get( 0 ).getColumnName().getText() );
|
||||
}
|
||||
|
||||
private TableSpecification getCollectionTable(String collectionOwner, String propertyName) {
|
||||
final EntityBinding entityBinding = metadata().getEntityBinding( collectionOwner );
|
||||
final PluralAttributeBinding binding = (PluralAttributeBinding) entityBinding.locateAttributeBinding( propertyName );
|
||||
return binding.getPluralAttributeKeyBinding().getCollectionTable();
|
||||
}
|
||||
|
||||
private ForeignKey getCollectionForeignKey(String collectionOwner, String propertyName) {
|
||||
final EntityBinding entityBinding = metadata().getEntityBinding( collectionOwner );
|
||||
final PluralAttributeBinding binding = (PluralAttributeBinding) entityBinding.locateAttributeBinding( propertyName );
|
||||
return binding.getPluralAttributeKeyBinding().getForeignKey();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
|
@ -306,7 +409,11 @@ public class CollectionElementTest extends BaseCoreFunctionalTestCase {
|
|||
LocalizedString.class,
|
||||
Toy.class,
|
||||
CountryAttitude.class,
|
||||
Brand.class
|
||||
Brand.class,
|
||||
Owner.class,
|
||||
BugSystem.class,
|
||||
Bug.class,
|
||||
Person.class
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.hibernate.test.annotations.collectionelement;
|
|||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
@ -21,6 +21,7 @@ import org.hibernate.annotations.Type;
|
|||
public class Matrix {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(name="mId")
|
||||
private Integer id;
|
||||
|
||||
@MapKeyType( @Type(type="integer") )
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.annotations.collectionelement;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@Entity( name="OWNER")
|
||||
@Table( name="OWNER_TABLE")
|
||||
public class Owner {
|
||||
private Integer id;
|
||||
private Set<String> elements = new HashSet<String>();
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ElementCollection
|
||||
public Set<String> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void setElements(Set<String> elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.KnownClient;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@Entity(name="CATEGORY")
|
||||
@Table(name="CATEGORY_TAB")
|
||||
public class Category {
|
||||
private Integer id;
|
||||
private Set<KnownClient> clients;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public Set<KnownClient> getClients() {
|
||||
return clients;
|
||||
}
|
||||
|
||||
public void setClients(Set<KnownClient> clients) {
|
||||
this.clients = clients;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
//$Id$
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.Item;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "tbl_city")
|
||||
public class City {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Set<Item> stolenItems;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public Set<Item> getStolenItems() {
|
||||
return stolenItems;
|
||||
}
|
||||
|
||||
public void setStolenItems(Set<Item> stolenItems) {
|
||||
this.stolenItems = stolenItems;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.util.List;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.PhoneNumber;
|
||||
|
||||
@Embeddable
|
||||
public class ContactInfo {
|
||||
// @ManyToOne
|
||||
// Address address; // Unidirectional
|
||||
|
||||
List<org.hibernate.test.annotations.manytomany.PhoneNumber> phoneNumbers; // Bidirectional
|
||||
|
||||
@ManyToMany(cascade= CascadeType.ALL)
|
||||
public List<org.hibernate.test.annotations.manytomany.PhoneNumber> getPhoneNumbers() {
|
||||
return phoneNumbers;
|
||||
}
|
||||
|
||||
public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
|
||||
this.phoneNumbers = phoneNumbers;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
//$Id$
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.test.annotations.manytomany.ContactInfo;
|
||||
import org.hibernate.test.annotations.manytomany.Employer;
|
||||
import org.hibernate.test.annotations.manytomany.JobInfo;
|
||||
|
||||
/**
|
||||
* Employee in an Employer-Employee relationship
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
@SuppressWarnings("serial")
|
||||
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() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer integer) {
|
||||
id = integer;
|
||||
}
|
||||
|
||||
@ManyToMany(
|
||||
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
|
||||
mappedBy = "employees"
|
||||
)
|
||||
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
|
||||
org.hibernate.annotations.CascadeType.PERSIST})
|
||||
public Collection<Employer> getEmployers() {
|
||||
return employers;
|
||||
}
|
||||
|
||||
public void setEmployers(Collection<Employer> employers) {
|
||||
this.employers = employers;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.*;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
*/
|
||||
@Entity(name="ITEM")
|
||||
public class Item {
|
||||
private Integer id;
|
||||
private Set<org.hibernate.test.annotations.manytomany.City> producedInCities;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(name="iId")
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public Set<org.hibernate.test.annotations.manytomany.City> getProducedInCities() {
|
||||
return producedInCities;
|
||||
}
|
||||
|
||||
public void setProducedInCities(Set<org.hibernate.test.annotations.manytomany.City> producedInCities) {
|
||||
this.producedInCities = producedInCities;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//$Id$
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.Store;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class KnownClient {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Set<Store> stores;
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToMany(mappedBy = "customers")
|
||||
public Set<Store> getStores() {
|
||||
return stores;
|
||||
}
|
||||
|
||||
public void setStores(Set<Store> stores) {
|
||||
this.stores = stores;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.mapping.ForeignKey;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.test.annotations.manytomany.Category;
|
||||
import org.hibernate.test.annotations.manytomany.City;
|
||||
import org.hibernate.test.annotations.manytomany.Contractor;
|
||||
import org.hibernate.test.annotations.manytomany.Employee;
|
||||
import org.hibernate.test.annotations.manytomany.Employer;
|
||||
import org.hibernate.test.annotations.manytomany.Item;
|
||||
import org.hibernate.test.annotations.manytomany.KnownClient;
|
||||
import org.hibernate.test.annotations.manytomany.PhoneNumber;
|
||||
import org.hibernate.test.annotations.manytomany.ProgramManager;
|
||||
import org.hibernate.test.annotations.manytomany.Store;
|
||||
import org.hibernate.test.annotations.manytomany.Supplier;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests default names for @JoinTable and @JoinColumn for unidirectional and bidirectional
|
||||
* many-to-many associations.
|
||||
*
|
||||
* NOTE: expected primary table names and join columns are explicit here to ensure that
|
||||
* entity names/tables and PK columns are not changed (which would invalidate these test cases).
|
||||
*
|
||||
* @author Gail Badner
|
||||
*/
|
||||
public class ManyToManyDefaultsTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Test
|
||||
public void testBidirNoOverrides() {
|
||||
// Employee.contactInfo.phoneNumbers: associated entity: PhoneNumber
|
||||
// both have @Entity with no name configured and default primary table names;
|
||||
// Primary table names default to unqualified entity classes.
|
||||
// PK column for Employee.id: id (default)
|
||||
// PK column for PhoneNumber.phNumber: phNumber (default)
|
||||
// bidirectional association
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Employee.class,
|
||||
"contactInfo.phoneNumbers",
|
||||
"employees",
|
||||
"Employee_PhoneNumber",
|
||||
"employees_id",
|
||||
"phoneNumbers_phNumber"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBidirOwnerPKOverride() {
|
||||
// Store.customers; associated entity: KnownClient
|
||||
// both have @Entity with no name configured and default primary table names
|
||||
// Primary table names default to unqualified entity classes.
|
||||
// PK column for Store.id: sId
|
||||
// PK column for KnownClient.id: id (default)
|
||||
// bidirectional association
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Store.class,
|
||||
"customers",
|
||||
"stores",
|
||||
"Store_KnownClient",
|
||||
"stores_sId",
|
||||
"customers_id"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerPKAssocEntityNamePKOverride() {
|
||||
// Store.items; associated entity: Item
|
||||
// Store has @Entity with no name configured and no @Table
|
||||
// Item has @Entity(name="ITEM") and no @Table
|
||||
// PK column for Store.id: sId
|
||||
// PK column for Item: iId
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Store.class,
|
||||
"items",
|
||||
null,
|
||||
"Store_ITEM",
|
||||
"Store_sId",
|
||||
"items_iId"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerPKAssocPrimaryTableNameOverride() {
|
||||
// Store.implantedIn; associated entity: City
|
||||
// Store has @Entity with no name configured and no @Table
|
||||
// City has @Entity with no name configured and @Table(name = "tbl_city")
|
||||
// PK column for Store.id: sId
|
||||
// PK column for City.id: id (default)
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Store.class,
|
||||
"implantedIn",
|
||||
null,
|
||||
"Store_tbl_city",
|
||||
"Store_sId",
|
||||
"implantedIn_id"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerPKAssocEntityNamePrimaryTableOverride() {
|
||||
// Store.categories; associated entity: Category
|
||||
// Store has @Entity with no name configured and no @Table
|
||||
// Category has @Entity(name="CATEGORY") @Table(name="CATEGORY_TAB")
|
||||
// PK column for Store.id: sId
|
||||
// PK column for Category.id: id (default)
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Store.class,
|
||||
"categories",
|
||||
null,
|
||||
"Store_CATEGORY_TAB",
|
||||
"Store_sId",
|
||||
"categories_id"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerEntityNamePKAssocPrimaryTableOverride() {
|
||||
// Item.producedInCities: associated entity: City
|
||||
// Item has @Entity(name="ITEM") and no @Table
|
||||
// City has @Entity with no name configured and @Table(name = "tbl_city")
|
||||
// PK column for Item: iId
|
||||
// PK column for City.id: id (default)
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Item.class,
|
||||
"producedInCities",
|
||||
null,
|
||||
"ITEM_tbl_city",
|
||||
"ITEM_iId",
|
||||
"producedInCities_id"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerPrimaryTableAssocEntityNamePKOverride() {
|
||||
// City.stolenItems; associated entity: Item
|
||||
// City has @Entity with no name configured and @Table(name = "tbl_city")
|
||||
// Item has @Entity(name="ITEM") and no @Table
|
||||
// PK column for City.id: id (default)
|
||||
// PK column for Item: iId
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
City.class,
|
||||
"stolenItems",
|
||||
null,
|
||||
"tbl_city_ITEM",
|
||||
"City_id",
|
||||
"stolenItems_iId"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidirOwnerEntityNamePrimaryTableOverride() {
|
||||
// Category.clients: associated entity: KnownClient
|
||||
// Category has @Entity(name="CATEGORY") @Table(name="CATEGORY_TAB")
|
||||
// KnownClient has @Entity with no name configured and no @Table
|
||||
// PK column for Category.id: id (default)
|
||||
// PK column for KnownClient.id: id (default)
|
||||
// unidirectional
|
||||
checkDefaultJoinTablAndJoinColumnNames(
|
||||
Category.class,
|
||||
"clients",
|
||||
null,
|
||||
"CATEGORY_TAB_KnownClient",
|
||||
"CATEGORY_id",
|
||||
"clients_id"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
private void checkDefaultJoinTablAndJoinColumnNames(
|
||||
Class<?> ownerEntityClass,
|
||||
String ownerCollectionPropertyName,
|
||||
String inverseCollectionPropertyName,
|
||||
String expectedCollectionTableName,
|
||||
String ownerForeignKeyNameExpected,
|
||||
String inverseForeignKeyNameExpected) {
|
||||
final org.hibernate.mapping.Collection collection = configuration().getCollectionMapping( ownerEntityClass.getName() + '.' + ownerCollectionPropertyName );
|
||||
final org.hibernate.mapping.Table table = collection.getCollectionTable();
|
||||
assertEquals( expectedCollectionTableName, table.getName() );
|
||||
|
||||
final org.hibernate.mapping.Collection ownerCollection = configuration().getCollectionMapping(
|
||||
ownerEntityClass.getName() + '.' + ownerCollectionPropertyName
|
||||
);
|
||||
// The default owner and inverse join columns can only be computed if they have PK with 1 column.
|
||||
assertEquals ( 1, ownerCollection.getOwner().getKey().getColumnSpan() );
|
||||
assertEquals( ownerForeignKeyNameExpected, ownerCollection.getKey().getColumnIterator().next().getText() );
|
||||
|
||||
final EntityType associatedEntityType = (EntityType) ownerCollection.getElement().getType();
|
||||
final PersistentClass associatedPersistentClass =
|
||||
configuration().getClassMapping( associatedEntityType.getAssociatedEntityName() );
|
||||
assertEquals( 1, associatedPersistentClass.getKey().getColumnSpan() );
|
||||
if ( inverseCollectionPropertyName != null ) {
|
||||
final org.hibernate.mapping.Collection inverseCollection = configuration().getCollectionMapping(
|
||||
associatedPersistentClass.getEntityName() + '.' + inverseCollectionPropertyName
|
||||
);
|
||||
assertEquals(
|
||||
inverseForeignKeyNameExpected,
|
||||
inverseCollection.getKey().getColumnIterator().next().getText()
|
||||
);
|
||||
}
|
||||
boolean hasOwnerFK = false;
|
||||
boolean hasInverseFK = false;
|
||||
for ( Iterator it=ownerCollection.getCollectionTable().getForeignKeyIterator(); it.hasNext(); ) {
|
||||
final ForeignKey fk = (ForeignKey) it.next();
|
||||
assertSame( ownerCollection.getCollectionTable(), fk.getTable() );
|
||||
if ( fk.getColumnSpan() > 1 ) {
|
||||
continue;
|
||||
}
|
||||
if ( fk.getColumn( 0 ).getText().equals( ownerForeignKeyNameExpected ) ) {
|
||||
assertSame( ownerCollection.getOwner().getTable(), fk.getReferencedTable() );
|
||||
hasOwnerFK = true;
|
||||
}
|
||||
else if ( fk.getColumn( 0 ).getText().equals( inverseForeignKeyNameExpected ) ) {
|
||||
assertSame( associatedPersistentClass.getTable(), fk.getReferencedTable() );
|
||||
hasInverseFK = true;
|
||||
}
|
||||
}
|
||||
assertTrue( hasOwnerFK );
|
||||
assertTrue( hasInverseFK );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[]{
|
||||
Category.class,
|
||||
City.class,
|
||||
Contractor.class,
|
||||
Employee.class,
|
||||
Employer.class,
|
||||
Item.class,
|
||||
KnownClient.class,
|
||||
PhoneNumber.class,
|
||||
ProgramManager.class,
|
||||
Store.class,
|
||||
Supplier.class
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.util.Collection;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.Employee;
|
||||
|
||||
@Entity
|
||||
public class PhoneNumber {
|
||||
int phNumber;
|
||||
Collection<org.hibernate.test.annotations.manytomany.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<org.hibernate.test.annotations.manytomany.Employee> getEmployees() {
|
||||
return employees;
|
||||
}
|
||||
|
||||
public void setEmployees(Collection<Employee> employees) {
|
||||
this.employees = employees;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
//$Id$
|
||||
package org.hibernate.test.annotations.manytomany.defaults;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
|
||||
import org.hibernate.test.annotations.manytomany.*;
|
||||
import org.hibernate.test.annotations.manytomany.City;
|
||||
import org.hibernate.test.annotations.manytomany.KnownClient;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Store {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Set<KnownClient> customers;
|
||||
private Set<Supplier> suppliers;
|
||||
private Set<Item> items;
|
||||
private Set<Category> categories;
|
||||
|
||||
@ManyToMany(cascade = CascadeType.PERSIST)
|
||||
public Set<org.hibernate.test.annotations.manytomany.City> getImplantedIn() {
|
||||
return implantedIn;
|
||||
}
|
||||
|
||||
public void setImplantedIn(Set<org.hibernate.test.annotations.manytomany.City> implantedIn) {
|
||||
this.implantedIn = implantedIn;
|
||||
}
|
||||
|
||||
private Set<City> implantedIn;
|
||||
|
||||
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinTable(
|
||||
name = "StoreSupplier",
|
||||
joinColumns = @JoinColumn(name = "store"),
|
||||
inverseJoinColumns = @JoinColumn(name = "supplier")
|
||||
)
|
||||
public Set<Supplier> getSuppliers() {
|
||||
return suppliers;
|
||||
}
|
||||
|
||||
public void setSuppliers(Set<Supplier> suppliers) {
|
||||
this.suppliers = suppliers;
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(name="sId")
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
public Set<KnownClient> getCustomers() {
|
||||
return customers;
|
||||
}
|
||||
|
||||
public void setCustomers(Set<KnownClient> customers) {
|
||||
this.customers = customers;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public Set<Item> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(Set<Item> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@ManyToMany
|
||||
public Set<Category> getCategories() {
|
||||
return categories;
|
||||
}
|
||||
|
||||
public void setCategories(Set<Category> categories) {
|
||||
this.categories = categories;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue