/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat, Inc. and/or it's affiliates, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.hibernate.test.cache.infinispan.functional.bulk;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory;
import org.hibernate.engine.transaction.spi.TransactionFactory;
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.jta.platform.spi.JtaPlatform;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.test.cache.infinispan.functional.Contact;
import org.hibernate.test.cache.infinispan.functional.Customer;
import org.hibernate.test.cache.infinispan.tm.JtaPlatformImpl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
/**
* BulkOperationsTestCase.
*
* @author Galder ZamarreƱo
* @since 3.5
*/
public class BulkOperationsTestCase extends BaseCoreFunctionalTestCase {
private TransactionManager tm;
@Override
public String[] getMappings() {
return new String[] {
"cache/infinispan/functional/Contact.hbm.xml",
"cache/infinispan/functional/Customer.hbm.xml"
};
}
@Override
public String getCacheConcurrencyStrategy() {
return "transactional";
}
protected Class<? extends RegionFactory> getCacheRegionFactory() {
return InfinispanRegionFactory.class;
}
protected Class<? extends TransactionFactory> getTransactionFactoryClass() {
return CMTTransactionFactory.class;
}
protected Class<? extends ConnectionProvider> getConnectionProviderClass() {
return org.hibernate.test.cache.infinispan.tm.XaConnectionProvider.class;
}
protected JtaPlatform getJtaPlatform() {
return new JtaPlatformImpl();
}
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.USE_QUERY_CACHE, "false" );
cfg.setProperty( Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName() );
cfg.setProperty( Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName() );
cfg.getProperties().put( AvailableSettings.JTA_PLATFORM, getJtaPlatform() );
cfg.setProperty( Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName() );
}
@Test
public void testBulkOperations() throws Throwable {
boolean cleanedUp = false;
try {
tm = getJtaPlatform().retrieveTransactionManager();
createContacts();
List<Integer> rhContacts = getContactsByCustomer( "Red Hat" );
assertNotNull( "Red Hat contacts exist", rhContacts );
assertEquals( "Created expected number of Red Hat contacts", 10, rhContacts.size() );
SecondLevelCacheStatistics contactSlcs = sessionFactory()
.getStatistics()
.getSecondLevelCacheStatistics( Contact.class.getName() );
assertEquals( 20, contactSlcs.getElementCountInMemory() );
assertEquals( "Deleted all Red Hat contacts", 10, deleteContacts() );
assertEquals( 0, contactSlcs.getElementCountInMemory() );
List<Integer> jbContacts = getContactsByCustomer( "JBoss" );
assertNotNull( "JBoss contacts exist", jbContacts );
assertEquals( "JBoss contacts remain", 10, jbContacts.size() );
for ( Integer id : rhContacts ) {
assertNull( "Red Hat contact " + id + " cannot be retrieved", getContact( id ) );
}
rhContacts = getContactsByCustomer( "Red Hat" );
if ( rhContacts != null ) {
assertEquals( "No Red Hat contacts remain", 0, rhContacts.size() );
}
updateContacts( "Kabir", "Updated" );
assertEquals( 0, contactSlcs.getElementCountInMemory() );
for ( Integer id : jbContacts ) {
Contact contact = getContact( id );
assertNotNull( "JBoss contact " + id + " exists", contact );
String expected = ("Kabir".equals( contact.getName() )) ? "Updated" : "2222";
assertEquals( "JBoss contact " + id + " has correct TLF", expected, contact.getTlf() );
}
List<Integer> updated = getContactsByTLF( "Updated" );
assertNotNull( "Got updated contacts", updated );
assertEquals( "Updated contacts", 5, updated.size() );
updateContactsWithOneManual( "Kabir", "UpdatedAgain" );
assertEquals( contactSlcs.getElementCountInMemory(), 0 );
for ( Integer id : jbContacts ) {
Contact contact = getContact( id );
assertNotNull( "JBoss contact " + id + " exists", contact );
String expected = ("Kabir".equals( contact.getName() )) ? "UpdatedAgain" : "2222";
assertEquals( "JBoss contact " + id + " has correct TLF", expected, contact.getTlf() );
}
updated = getContactsByTLF( "UpdatedAgain" );
assertNotNull( "Got updated contacts", updated );
assertEquals( "Updated contacts", 5, updated.size() );
}
catch (Throwable t) {
cleanedUp = true;
cleanup( true );
throw t;
}
finally {
// cleanup the db so we can run this test multiple times w/o restarting the cluster
if ( !cleanedUp ) {
cleanup( false );
}
}
}
public void createContacts() throws Exception {
tm.begin();
try {
for ( int i = 0; i < 10; i++ ) {
createCustomer( i );
}
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
public int deleteContacts() throws Exception {
String deleteHQL = "delete Contact where customer in ";
deleteHQL += " (select customer FROM Customer as customer ";
deleteHQL += " where customer.name = :cName)";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
int rowsAffected = session.createQuery( deleteHQL ).setFlushMode( FlushMode.AUTO )
.setParameter( "cName", "Red Hat" ).executeUpdate();
tm.commit();
return rowsAffected;
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
try {
tm.rollback();
}
catch (Exception ee) {
// ignored
}
}
}
}
@SuppressWarnings( {"unchecked"})
public List<Integer> getContactsByCustomer(String customerName) throws Exception {
String selectHQL = "select contact.id from Contact contact";
selectHQL += " where contact.customer.name = :cName";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
return session.createQuery( selectHQL )
.setFlushMode( FlushMode.AUTO )
.setParameter( "cName", customerName )
.list();
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
@SuppressWarnings( {"unchecked"})
public List<Integer> getContactsByTLF(String tlf) throws Exception {
String selectHQL = "select contact.id from Contact contact";
selectHQL += " where contact.tlf = :cTLF";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
return session.createQuery( selectHQL )
.setFlushMode( FlushMode.AUTO )
.setParameter( "cTLF", tlf )
.list();
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
public int updateContacts(String name, String newTLF) throws Exception {
String updateHQL = "update Contact set tlf = :cNewTLF where name = :cName";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
return session.createQuery( updateHQL )
.setFlushMode( FlushMode.AUTO )
.setParameter( "cNewTLF", newTLF )
.setParameter( "cName", name )
.executeUpdate();
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
public int updateContactsWithOneManual(String name, String newTLF) throws Exception {
String queryHQL = "from Contact c where c.name = :cName";
String updateHQL = "update Contact set tlf = :cNewTLF where name = :cName";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
@SuppressWarnings("unchecked")
List<Contact> list = session.createQuery( queryHQL ).setParameter( "cName", name ).list();
list.get( 0 ).setTlf( newTLF );
return session.createQuery( updateHQL )
.setFlushMode( FlushMode.AUTO )
.setParameter( "cNewTLF", newTLF )
.setParameter( "cName", name )
.executeUpdate();
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
public Contact getContact(Integer id) throws Exception {
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
return (Contact) session.get( Contact.class, id );
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
tm.rollback();
}
}
}
public void cleanup(boolean ignore) throws Exception {
String deleteContactHQL = "delete from Contact";
String deleteCustomerHQL = "delete from Customer";
tm.begin();
try {
Session session = sessionFactory().getCurrentSession();
session.createQuery( deleteContactHQL ).setFlushMode( FlushMode.AUTO ).executeUpdate();
session.createQuery( deleteCustomerHQL ).setFlushMode( FlushMode.AUTO ).executeUpdate();
}
catch (Exception e) {
tm.setRollbackOnly();
throw e;
}
finally {
if ( tm.getStatus() == Status.STATUS_ACTIVE ) {
tm.commit();
}
else {
if ( !ignore ) {
try {
tm.rollback();
}
catch (Exception ee) {
// ignored
}
}
}
}
}
private Customer createCustomer(int id) throws Exception {
System.out.println( "CREATE CUSTOMER " + id );
try {
Customer customer = new Customer();
customer.setName( (id % 2 == 0) ? "JBoss" : "Red Hat" );
Set<Contact> contacts = new HashSet<Contact>();
Contact kabir = new Contact();
kabir.setCustomer( customer );
kabir.setName( "Kabir" );
kabir.setTlf( "1111" );
contacts.add( kabir );
Contact bill = new Contact();
bill.setCustomer( customer );
bill.setName( "Bill" );
bill.setTlf( "2222" );
contacts.add( bill );
customer.setContacts( contacts );
Session s = openSession();
s.getTransaction().begin();
s.persist( customer );
s.getTransaction().commit();
s.close();
return customer;
}
finally {
System.out.println( "CREATE CUSTOMER " + id + " - END" );
}
}
}