/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, 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.indexcoll;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.junit.Test;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Test index collections
*
* @author Emmanuel Bernard
*/
public class IndexedCollectionTest extends BaseCoreFunctionalTestCase {
@Test
public void testJPA2DefaultMapColumns() throws Exception {
isDefaultKeyColumnPresent( Atmosphere.class.getName(), "gasesDef", "_KEY" );
isDefaultKeyColumnPresent( Atmosphere.class.getName(), "gasesPerKeyDef", "_KEY" );
isDefaultKeyColumnPresent( Atmosphere.class.getName(), "gasesDefLeg", "_KEY" );
}
@Test
public void testJPA2DefaultIndexColumns() throws Exception {
isDefaultKeyColumnPresent( Drawer.class.getName(), "dresses", "_ORDER" );
}
private void isDefaultKeyColumnPresent(String collectionOwner, String propertyName, String suffix) {
assertTrue( "Could not find " + propertyName + suffix,
isDefaultColumnPresent(collectionOwner, propertyName, suffix) );
}
private boolean isDefaultColumnPresent(String collectionOwner, String propertyName, String suffix) {
final Collection collection = configuration().getCollectionMapping( collectionOwner + "." + propertyName );
final Iterator columnIterator = collection.getCollectionTable().getColumnIterator();
boolean hasDefault = false;
while ( columnIterator.hasNext() ) {
Column column = (Column) columnIterator.next();
if ( (propertyName + suffix).equals( column.getName() ) ) hasDefault = true;
}
return hasDefault;
}
private void isNotDefaultKeyColumnPresent(String collectionOwner, String propertyName, String suffix) {
assertFalse( "Could not find " + propertyName + suffix,
isDefaultColumnPresent(collectionOwner, propertyName, suffix) );
}
@Test
public void testFkList() throws Exception {
Wardrobe w = new Wardrobe();
Drawer d1 = new Drawer();
Drawer d2 = new Drawer();
w.setDrawers( new ArrayList<Drawer>() );
w.getDrawers().add( d1 );
w.getDrawers().add( d2 );
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
s.persist( w );
s.flush();
s.clear();
w = (Wardrobe) s.get( Wardrobe.class, w.getId() );
assertNotNull( w );
assertNotNull( w.getDrawers() );
List<Drawer> result = w.getDrawers();
assertEquals( 2, result.size() );
assertEquals( d2.getId(), result.get( 1 ).getId() );
result.remove( d1 );
s.flush();
d1 = (Drawer) s.merge( d1 );
result.add( d1 );
s.flush();
s.clear();
w = (Wardrobe) s.get( Wardrobe.class, w.getId() );
assertNotNull( w );
assertNotNull( w.getDrawers() );
result = w.getDrawers();
assertEquals( 2, result.size() );
assertEquals( d1.getId(), result.get( 1 ).getId() );
s.delete( result.get( 0 ) );
s.delete( result.get( 1 ) );
s.delete( w );
s.flush();
tx.rollback();
s.close();
}
@Test
public void testJoinedTableList() throws Exception {
Wardrobe w = new Wardrobe();
w.setDrawers( new ArrayList<Drawer>() );
Drawer d = new Drawer();
w.getDrawers().add( d );
Dress d1 = new Dress();
Dress d2 = new Dress();
d.setDresses( new ArrayList<Dress>() );
d.getDresses().add( d1 );
d.getDresses().add( d2 );
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
s.persist( d1 );
s.persist( d2 );
s.persist( w );
s.flush();
s.clear();
d = (Drawer) s.get( Drawer.class, d.getId() );
assertNotNull( d );
assertNotNull( d.getDresses() );
List<Dress> result = d.getDresses();
assertEquals( 2, result.size() );
assertEquals( d2.getId(), result.get( 1 ).getId() );
result.remove( d1 );
s.flush();
d1 = (Dress) s.merge( d1 );
result.add( d1 );
s.flush();
s.clear();
d = (Drawer) s.get( Drawer.class, d.getId() );
assertNotNull( d );
assertNotNull( d.getDresses() );
result = d.getDresses();
assertEquals( 2, result.size() );
assertEquals( d1.getId(), result.get( 1 ).getId() );
s.delete( result.get( 0 ) );
s.delete( result.get( 1 ) );
s.delete( d );
s.flush();
tx.rollback();
s.close();
}
@Test
public void testMapKey() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Software hibernate = new Software();
hibernate.setName( "Hibernate" );
Version v1 = new Version();
v1.setCodeName( "HumbaHumba" );
v1.setNumber( "1.0" );
v1.setSoftware( hibernate );
Version v2 = new Version();
v2.setCodeName( "Copacabana" );
v2.setNumber( "2.0" );
v2.setSoftware( hibernate );
Version v4 = new Version();
v4.setCodeName( "Dreamland" );
v4.setNumber( "4.0" );
v4.setSoftware( hibernate );
Map<String, Version> link = new HashMap<String, Version>();
link.put( v1.getCodeName(), v1 );
link.put( v2.getCodeName(), v2 );
link.put( v4.getCodeName(), v4 );
hibernate.setVersions( link );
s.persist( hibernate );
s.persist( v1 );
s.persist( v2 );
s.persist( v4 );
s.flush();
s.clear();
hibernate = (Software) s.get( Software.class, "Hibernate" );
assertEquals( 3, hibernate.getVersions().size() );
assertEquals( "1.0", hibernate.getVersions().get( "HumbaHumba" ).getNumber() );
assertEquals( "2.0", hibernate.getVersions().get( "Copacabana" ).getNumber() );
hibernate.getVersions().remove( v4.getCodeName() );
s.flush();
s.clear();
hibernate = (Software) s.get( Software.class, "Hibernate" );
assertEquals( "So effect on collection changes", 3, hibernate.getVersions().size() );
for ( Version v : hibernate.getVersions().values() ) {
s.delete( v );
}
s.delete( hibernate );
s.flush();
tx.rollback();
s.close();
}
@Test
public void testDefaultMapKey() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
AddressBook book = new AddressBook();
book.setOwner( "Emmanuel" );
AddressEntryPk helene = new AddressEntryPk( "Helene", "Michau" );
AddressEntry heleneEntry = new AddressEntry();
heleneEntry.setBook( book );
heleneEntry.setCity( "Levallois" );
heleneEntry.setStreet( "Louis Blanc" );
heleneEntry.setPerson( helene );
AddressEntryPk primeMinister = new AddressEntryPk( "Dominique", "Villepin" );
AddressEntry primeMinisterEntry = new AddressEntry();
primeMinisterEntry.setBook( book );
primeMinisterEntry.setCity( "Paris" );
primeMinisterEntry.setStreet( "Hotel Matignon" );
primeMinisterEntry.setPerson( primeMinister );
book.getEntries().put( helene, heleneEntry );
book.getEntries().put( primeMinister, primeMinisterEntry );
s.persist( book );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 2, book.getEntries().size() );
assertEquals( heleneEntry.getCity(), book.getEntries().get( helene ).getCity() );
AddressEntryPk fake = new AddressEntryPk( "Fake", "Fake" );
book.getEntries().put( fake, primeMinisterEntry );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 2, book.getEntries().size() );
assertNull( book.getEntries().get( fake ) );
s.delete( book );
s.flush();
tx.rollback();
s.close();
}
@Test
public void testMapKeyToEntity() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
AlphabeticalDirectory m = new AlphabeticalDirectory();
m.setName( "M" );
AlphabeticalDirectory v = new AlphabeticalDirectory();
v.setName( "V" );
s.persist( m );
s.persist( v );
AddressBook book = new AddressBook();
book.setOwner( "Emmanuel" );
AddressEntryPk helene = new AddressEntryPk( "Helene", "Michau" );
AddressEntry heleneEntry = new AddressEntry();
heleneEntry.setBook( book );
heleneEntry.setCity( "Levallois" );
heleneEntry.setStreet( "Louis Blanc" );
heleneEntry.setPerson( helene );
heleneEntry.setDirectory( m );
AddressEntryPk primeMinister = new AddressEntryPk( "Dominique", "Villepin" );
AddressEntry primeMinisterEntry = new AddressEntry();
primeMinisterEntry.setBook( book );
primeMinisterEntry.setCity( "Paris" );
primeMinisterEntry.setStreet( "Hotel Matignon" );
primeMinisterEntry.setPerson( primeMinister );
primeMinisterEntry.setDirectory( v );
book.getEntries().put( helene, heleneEntry );
book.getEntries().put( primeMinister, primeMinisterEntry );
s.persist( book );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 2, book.getEntries().size() );
assertEquals( heleneEntry.getCity(), book.getEntries().get( helene ).getCity() );
assertEquals( "M", book.getEntries().get( helene ).getDirectory().getName() );
s.delete( book );
tx.rollback();
s.close();
}
@Test
@RequiresDialect({HSQLDialect.class, H2Dialect.class})
public void testComponentSubPropertyMapKey() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
AddressBook book = new AddressBook();
book.setOwner( "Emmanuel" );
AddressEntryPk helene = new AddressEntryPk( "Helene", "Michau" );
AddressEntry heleneEntry = new AddressEntry();
heleneEntry.setBook( book );
heleneEntry.setCity( "Levallois" );
heleneEntry.setStreet( "Louis Blanc" );
heleneEntry.setPerson( helene );
AddressEntryPk primeMinister = new AddressEntryPk( "Dominique", "Villepin" );
AddressEntry primeMinisterEntry = new AddressEntry();
primeMinisterEntry.setBook( book );
primeMinisterEntry.setCity( "Paris" );
primeMinisterEntry.setStreet( "Hotel Matignon" );
primeMinisterEntry.setPerson( primeMinister );
book.getEntries().put( helene, heleneEntry );
book.getEntries().put( primeMinister, primeMinisterEntry );
s.persist( book );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 2, book.getLastNameEntries().size() );
assertEquals( heleneEntry.getCity(), book.getLastNameEntries().get( "Michau" ).getCity() );
AddressEntryPk fake = new AddressEntryPk( "Fake", "Fake" );
book.getEntries().put( fake, primeMinisterEntry );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 2, book.getEntries().size() );
assertNull( book.getEntries().get( fake ) );
s.delete( book );
tx.rollback();
s.close();
}
@Test
public void testMapKeyOnManyToMany() throws Exception {
Session s;
s = openSession();
s.getTransaction().begin();
News airplane = new News();
airplane.setTitle( "Crash!" );
airplane.setDetail( "An airplaned crashed." );
s.persist( airplane );
Newspaper lemonde = new Newspaper();
lemonde.setName( "Lemonde" );
lemonde.getNews().put( airplane.getTitle(), airplane );
s.persist( lemonde );
s.flush();
s.clear();
lemonde = (Newspaper) s.get( Newspaper.class, lemonde.getId() );
assertEquals( 1, lemonde.getNews().size() );
News news = lemonde.getNews().get( airplane.getTitle() );
assertNotNull( news );
assertEquals( airplane.getTitle(), news.getTitle() );
s.delete( lemonde );
s.delete( news );
s.getTransaction().rollback();
s.close();
}
@Test
public void testMapKeyOnManyToManyOnId() throws Exception {
Session s;
s = openSession();
s.getTransaction().begin();
News hibernate1 = new News();
hibernate1.setTitle( "#1 ORM solution in the Java world" );
hibernate1.setDetail( "Well, that's no news ;-)" );
s.persist( hibernate1 );
PressReleaseAgency schwartz = new PressReleaseAgency();
schwartz.setName( "Schwartz" );
schwartz.getProvidedNews().put( hibernate1.getId(), hibernate1 );
s.persist( schwartz );
s.flush();
s.clear();
schwartz = (PressReleaseAgency) s.get( PressReleaseAgency.class, schwartz.getId() );
assertEquals( 1, schwartz.getProvidedNews().size() );
News news = schwartz.getProvidedNews().get( hibernate1.getId() );
assertNotNull( news );
assertEquals( hibernate1.getTitle(), news.getTitle() );
s.delete( schwartz );
s.delete( news );
s.getTransaction().rollback();
s.close();
}
@Test
public void testMapKeyAndIdClass() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Painter picasso = new Painter();
Painting laVie = new Painting( "La Vie", "Picasso", 50, 20 );
picasso.getPaintings().put( "La Vie", laVie );
Painting famille = new Painting( "La Famille du Saltimbanque", "Picasso", 50, 20 );
picasso.getPaintings().put( "La Famille du Saltimbanque", famille );
s.persist( picasso );
s.flush();
s.clear();
picasso = (Painter) s.get( Painter.class, picasso.getId() );
Painting painting = picasso.getPaintings().get( famille.getName() );
assertNotNull( painting );
assertEquals( painting.getName(), famille.getName() );
s.delete( picasso );
tx.rollback();
s.close();
}
@Test
public void testRealMap() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Atmosphere atm = new Atmosphere();
Atmosphere atm2 = new Atmosphere();
GasKey key = new GasKey();
key.setName( "O2" );
Gas o2 = new Gas();
o2.name = "oxygen";
atm.gases.put( "100%", o2 );
atm.gasesPerKey.put( key, o2 );
atm2.gases.put( "100%", o2 );
atm2.gasesPerKey.put( key, o2 );
s.persist( key );
s.persist( atm );
s.persist( atm2 );
s.flush();
s.clear();
atm = (Atmosphere) s.get( Atmosphere.class, atm.id );
key = (GasKey) s.get( GasKey.class, key.getName() );
assertEquals( 1, atm.gases.size() );
assertEquals( o2.name, atm.gases.get( "100%" ).name );
assertEquals( o2.name, atm.gasesPerKey.get( key ).name );
tx.rollback();
s.close();
}
@Test
public void testTemporalKeyMap() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Atmosphere atm = new Atmosphere();
atm.colorPerDate.put( new Date(1234567000), "red" );
s.persist( atm );
s.flush();
s.clear();
atm = (Atmosphere) s.get( Atmosphere.class, atm.id );
assertEquals( 1, atm.colorPerDate.size() );
final Date date = atm.colorPerDate.keySet().iterator().next();
final long diff = new Date( 1234567000 ).getTime() - date.getTime();
assertTrue( "24h diff max", diff > 0 && diff < 24*60*60*1000 );
tx.rollback();
s.close();
}
@Test
public void testEnumKeyType() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Atmosphere atm = new Atmosphere();
atm.colorPerLevel.put( Atmosphere.Level.HIGH, "red" );
s.persist( atm );
s.flush();
s.clear();
atm = (Atmosphere) s.get( Atmosphere.class, atm.id );
assertEquals( 1, atm.colorPerLevel.size() );
assertEquals( "red", atm.colorPerLevel.get(Atmosphere.Level.HIGH) );
tx.rollback();
s.close();
}
@Test
public void testMapKeyEntityEntity() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
AddressBook book = new AddressBook();
s.persist( book );
AddressEntry entry = new AddressEntry();
entry.setCity( "Atlanta");
AddressEntryPk pk = new AddressEntryPk("Coca", "Cola" );
entry.setPerson( pk );
entry.setBook( book );
AlphabeticalDirectory ad = new AlphabeticalDirectory();
ad.setName( "C");
s.persist( ad );
entry.setDirectory( ad );
s.persist( entry );
book.getDirectoryEntries().put( ad, entry );
s.flush();
s.clear();
book = (AddressBook) s.get( AddressBook.class, book.getId() );
assertEquals( 1, book.getDirectoryEntries().size() );
assertEquals( "C", book.getDirectoryEntries().keySet().iterator().next().getName() );
tx.rollback();
s.close();
}
@Test
public void testEntityKeyElementTarget() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Atmosphere atm = new Atmosphere();
Gas o2 = new Gas();
o2.name = "oxygen";
atm.composition.put( o2, 94.3 );
s.persist( o2 );
s.persist( atm );
s.flush();
s.clear();
atm = (Atmosphere) s.get( Atmosphere.class, atm.id );
assertTrue( ! Hibernate.isInitialized( atm.composition ) );
assertEquals( 1, atm.composition.size() );
assertEquals( o2.name, atm.composition.keySet().iterator().next().name );
tx.rollback();
s.close();
}
@Test
public void testSortedMap() {
Session s = openSession();
Transaction tx = s.beginTransaction();
Training training = new Training();
Trainee trainee = new Trainee();
trainee.setName( "Jim" );
Trainee trainee2 = new Trainee();
trainee2.setName( "Emmanuel" );
s.persist( trainee );
s.persist( trainee2 );
training.getTrainees().put( "Jim", trainee );
training.getTrainees().put( "Emmanuel", trainee2 );
s.persist( training );
s.flush();
s.clear();
training = (Training) s.get( Training.class, training.getId() );
assertEquals( "Emmanuel", training.getTrainees().firstKey() );
assertEquals( "Jim", training.getTrainees().lastKey() );
tx.rollback();
s.close();
}
@Test
public void testMapKeyLoad() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Software hibernate = new Software();
hibernate.setName( "Hibernate" );
Version v1 = new Version();
v1.setCodeName( "HumbaHumba" );
v1.setNumber( "1.0" );
v1.setSoftware( hibernate );
hibernate.addVersion( v1 );
s.persist( hibernate );
s.persist( v1 );
s.flush();
s.clear();
hibernate = (Software) s.get( Software.class, "Hibernate" );
assertEquals(1, hibernate.getVersions().size() );
Version v2 = new Version();
v2.setCodeName( "HumbaHumba2" );
v2.setNumber( "2.0" );
v2.setSoftware( hibernate );
hibernate.addVersion( v2 );
assertEquals( "One loaded persisted version, and one just added", 2, hibernate.getVersions().size() );
s.flush();
s.clear();
hibernate = (Software) s.get( Software.class, "Hibernate" );
for ( Version v : hibernate.getVersions().values() ) {
s.delete( v );
}
s.delete( hibernate );
tx.rollback();
s.close();
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{
Wardrobe.class,
Drawer.class,
Dress.class,
Software.class,
Version.class,
AddressBook.class,
AddressEntry.class,
AddressEntryPk.class, //should be silently ignored
Newspaper.class,
News.class,
PressReleaseAgency.class,
Painter.class,
Painting.class,
Atmosphere.class,
Gas.class,
AlphabeticalDirectory.class,
GasKey.class,
Trainee.class,
Training.class
};
}
}