Hibernate SVN: r18014 - in search/trunk/src: test/java/org/hibernate/search/test/id/providedId and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-11-20 06:21:01 -0500 (Fri, 20 Nov 2009)
New Revision: 18014
Added:
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ManualTransactionContext.java
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/StandaloneConf.java
Modified:
search/trunk/src/main/java/org/hibernate/search/backend/WorkQueue.java
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPersonSub.java
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java
Log:
HSEARCH-419 proper provided id test not using the Hibernate Core backend.
Modified: search/trunk/src/main/java/org/hibernate/search/backend/WorkQueue.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/backend/WorkQueue.java 2009-11-20 09:57:30 UTC (rev 18013)
+++ search/trunk/src/main/java/org/hibernate/search/backend/WorkQueue.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -26,6 +26,7 @@
import java.util.List;
import java.util.ArrayList;
+import java.util.Collections;
import org.hibernate.annotations.common.AssertionFailure;
@@ -73,7 +74,7 @@
public void setSealedQueue(List<LuceneWork> sealedQueue) {
//invalidate the working queue for serializability
- queue = null;
+ queue = Collections.EMPTY_LIST;
this.sealedQueue = sealedQueue;
}
Added: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ManualTransactionContext.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ManualTransactionContext.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ManualTransactionContext.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -0,0 +1,39 @@
+package org.hibernate.search.test.id.providedId;
+
+import java.util.List;
+import java.util.ArrayList;
+import javax.transaction.Synchronization;
+import javax.transaction.Status;
+
+import org.hibernate.search.backend.TransactionContext;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ManualTransactionContext implements TransactionContext {
+ private boolean progress = true;
+ private List<Synchronization> syncs = new ArrayList<Synchronization>();
+
+ public boolean isTransactionInProgress() {
+ return progress;
+ }
+
+ public Object getTransactionIdentifier() {
+ return this;
+ }
+
+ public void registerSynchronization(Synchronization synchronization) {
+ syncs.add(synchronization);
+ }
+
+ public void end() {
+ this.progress = false;
+ for (Synchronization sync : syncs) {
+ sync.beforeCompletion();
+ }
+
+ for (Synchronization sync : syncs) {
+ sync.afterCompletion( Status.STATUS_COMMITTED );
+ }
+ }
+}
Modified: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java 2009-11-20 09:57:30 UTC (rev 18013)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -41,13 +41,13 @@
/**
* @author Navin Surtani
*/
-@Entity
+//@Entity
@ProvidedId(bridge = @FieldBridge(impl = LongBridge.class) )
@Indexed
public class ProvidedIdPerson implements Serializable {
- @Id
- @GeneratedValue
+// @Id
+// @GeneratedValue
private long id;
@Field(index = Index.TOKENIZED, store = Store.YES)
Modified: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPersonSub.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPersonSub.java 2009-11-20 09:57:30 UTC (rev 18013)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPersonSub.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -32,6 +32,5 @@
* @author Navin Surtani (<a href="mailto:nsurtani@redhat.com">nsurtani(a)redhat.com</a>)
*/
@Indexed
-@Entity
public class ProvidedIdPersonSub extends ProvidedIdPerson {
}
Modified: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java 2009-11-20 09:57:30 UTC (rev 18013)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdTest.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -34,22 +34,22 @@
import org.hibernate.Transaction;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
+import org.hibernate.search.SearchFactory;
+import org.hibernate.search.engine.SearchFactoryImplementor;
+import org.hibernate.search.backend.Work;
+import org.hibernate.search.backend.WorkType;
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.impl.SearchFactoryImpl;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.test.SearchTestCase;
/**
* @author Navin Surtani
*/
-public class ProvidedIdTest extends SearchTestCase {
+public class ProvidedIdTest extends junit.framework.TestCase {
- protected Class[] getMappings() {
- return new Class[] {
- ProvidedIdPerson.class,
- ProvidedIdPersonSub.class
- };
- }
-
public void testProvidedId() throws Exception {
+ SearchFactoryImplementor sf = new SearchFactoryImpl( new StandaloneConf() );
ProvidedIdPerson person1 = new ProvidedIdPerson();
person1.setName( "Big Goat" );
@@ -63,17 +63,16 @@
person3.setName( "Regular goat" );
person3.setBlurb( "Is anorexic" );
- Session session = openSession();
- FullTextSession fullTextSession = Search.getFullTextSession( session );
- Transaction transaction = session.beginTransaction();
- session.persist( person1 );
- session.persist( person2 );
- session.persist( person3 );
+ ManualTransactionContext tc = new ManualTransactionContext();
- transaction.commit();
- session.clear();
+ Work<ProvidedIdPerson> work = new Work<ProvidedIdPerson>( person1, 1, WorkType.INDEX );
+ sf.getWorker().performWork( work, tc );
+ work = new Work<ProvidedIdPerson>( person2, 2, WorkType.INDEX );
+ sf.getWorker().performWork( work, tc );
+ Work<ProvidedIdPersonSub> work2 = new Work<ProvidedIdPersonSub>( person3, 3, WorkType.INDEX );
+ sf.getWorker().performWork( work2, tc );
- transaction = fullTextSession.beginTransaction();
+ tc.end();
QueryParser parser = new QueryParser( "name", new StandardAnalyzer() );
Query luceneQuery = parser.parse( "Goat" );
@@ -82,15 +81,12 @@
//needs it. So we use plain Lucene
//we know there is only one DP
- DirectoryProvider provider = fullTextSession.getSearchFactory()
+ DirectoryProvider provider = sf
.getDirectoryProviders( ProvidedIdPerson.class )[0];
IndexSearcher searcher = new IndexSearcher( provider.getDirectory() );
TopDocs hits = searcher.search( luceneQuery, 1000 );
- searcher.close();
- transaction.commit();
- session.close();
-
assertEquals( 3, hits.totalHits );
+ searcher.close();
}
Added: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/StandaloneConf.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/StandaloneConf.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/StandaloneConf.java 2009-11-20 11:21:01 UTC (rev 18014)
@@ -0,0 +1,60 @@
+package org.hibernate.search.test.id.providedId;
+
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.lucene.analysis.StopAnalyzer;
+
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.store.RAMDirectoryProvider;
+import org.hibernate.search.Environment;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class StandaloneConf implements SearchConfiguration {
+ final Map<String,Class<?>> classes;
+ final Properties properties;
+
+ public StandaloneConf() {
+ classes = new HashMap<String,Class<?>>(2);
+ classes.put( ProvidedIdPerson.class.getName(), ProvidedIdPerson.class );
+ classes.put( ProvidedIdPersonSub.class.getName(), ProvidedIdPersonSub.class );
+
+ properties = new Properties( );
+ properties.setProperty( "hibernate.search.default.directory_provider", RAMDirectoryProvider.class.getName() );
+ properties.setProperty( Environment.ANALYZER_CLASS, StopAnalyzer.class.getName() );
+ properties.setProperty( "hibernate.search.default.transaction.merge_factor", "100" );
+ properties.setProperty( "hibernate.search.default.batch.max_buffered_docs", "1000" );
+ }
+
+ public Iterator<Class<?>> getClassMappings() {
+ return classes.values().iterator();
+ }
+
+ public Class<?> getClassMapping(String name) {
+ return classes.get( name );
+ }
+
+ public String getProperty(String propertyName) {
+ return properties.getProperty( propertyName );
+ }
+
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public ReflectionManager getReflectionManager() {
+ return null;
+ }
+
+ public SearchMapping getProgrammaticMapping() {
+ return null;
+ }
+}
15 years
Hibernate SVN: r18013 - in validator/trunk/hibernate-validator-annotation-processor/src/main/resources: META-INF and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-11-20 04:57:30 -0500 (Fri, 20 Nov 2009)
New Revision: 18013
Added:
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/services/
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
Log:
HV-269 added service file
Added: validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor 2009-11-20 09:57:30 UTC (rev 18013)
@@ -0,0 +1 @@
+org.hibernate.validator.ap.ConstraintValidationProcessor
\ No newline at end of file
15 years
Hibernate SVN: r18012 - in core/trunk: core/src/main/java/org/hibernate/impl and 5 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-11-20 00:20:28 -0500 (Fri, 20 Nov 2009)
New Revision: 18012
Modified:
core/trunk/core/src/main/java/org/hibernate/Criteria.java
core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java
core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java
core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java
core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java
core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java
core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
core/trunk/documentation/manual/src/main/docbook/en-US/content/query_criteria.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
Log:
HHH-2308 - Adding predicates to the join condition using Criteria Query
Modified: core/trunk/core/src/main/java/org/hibernate/Criteria.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Criteria.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/Criteria.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -135,7 +135,10 @@
*
* @param associationPath a dot seperated property path
* @param mode The fetch mode for the referenced association
+ *
* @return this (for method chaining)
+ *
+ * @throws HibernateException Indicates a problem applying the given fetch mode
*/
public Criteria setFetchMode(String associationPath, FetchMode mode) throws HibernateException;
@@ -143,6 +146,7 @@
* Set the lock mode of the current entity
*
* @param lockMode The lock mode to be applied
+ *
* @return this (for method chaining)
*/
public Criteria setLockMode(LockMode lockMode);
@@ -151,8 +155,9 @@
* Set the lock mode of the aliased entity
*
* @param alias The previously assigned alias representing the entity to
- * which the given lock mode should apply.
+ * which the given lock mode should apply.
* @param lockMode The lock mode to be applied
+ *
* @return this (for method chaining)
*/
public Criteria setLockMode(String alias, LockMode lockMode);
@@ -165,7 +170,10 @@
*
* @param associationPath A dot-seperated property path
* @param alias The alias to assign to the joined association (for later reference).
+ *
* @return this (for method chaining)
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createAlias(String associationPath, String alias) throws HibernateException;
@@ -179,18 +187,42 @@
* @param associationPath A dot-seperated property path
* @param alias The alias to assign to the joined association (for later reference).
* @param joinType The type of join to use.
+ *
* @return this (for method chaining)
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException;
/**
+ * Join an association using the specified join-type, assigning an alias
+ * to the joined association.
+ * <p/>
+ * The joinType is expected to be one of {@link #INNER_JOIN} (the default),
+ * {@link #FULL_JOIN}, or {@link #LEFT_JOIN}.
+ *
+ * @param associationPath A dot-seperated property path
+ * @param alias The alias to assign to the joined association (for later reference).
+ * @param joinType The type of join to use.
+ * @param withClause The criteria to be added to the join condition (<tt>ON</tt> clause)
+ *
+ * @return this (for method chaining)
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
+ */
+ public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException;
+
+ /**
* Create a new <tt>Criteria</tt>, "rooted" at the associated entity.
* <p/>
* Functionally equivalent to {@link #createCriteria(String, int)} using
* {@link #INNER_JOIN} for the joinType.
*
* @param associationPath A dot-seperated property path
+ *
* @return the created "sub criteria"
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createCriteria(String associationPath) throws HibernateException;
@@ -200,7 +232,10 @@
*
* @param associationPath A dot-seperated property path
* @param joinType The type of join to use.
+ *
* @return the created "sub criteria"
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createCriteria(String associationPath, int joinType) throws HibernateException;
@@ -213,7 +248,10 @@
*
* @param associationPath A dot-seperated property path
* @param alias The alias to assign to the joined association (for later reference).
+ *
* @return the created "sub criteria"
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createCriteria(String associationPath, String alias) throws HibernateException;
@@ -224,11 +262,29 @@
* @param associationPath A dot-seperated property path
* @param alias The alias to assign to the joined association (for later reference).
* @param joinType The type of join to use.
+ *
* @return the created "sub criteria"
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
*/
public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException;
/**
+ * Create a new <tt>Criteria</tt>, "rooted" at the associated entity,
+ * assigning the given alias and using the specified join type.
+ *
+ * @param associationPath A dot-seperated property path
+ * @param alias The alias to assign to the joined association (for later reference).
+ * @param joinType The type of join to use.
+ * @param withClause The criteria to be added to the join condition (<tt>ON</tt> clause)
+ *
+ * @return the created "sub criteria"
+ *
+ * @throws HibernateException Indicates a problem creating the sub criteria
+ */
+ public Criteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException;
+
+ /**
* Set a strategy for handling the query results. This determines the
* "shape" of the query result.
*
@@ -327,6 +383,9 @@
* Get the results.
*
* @return The list of matched query results.
+ *
+ * @throws HibernateException Indicates a problem either translating the criteria to SQL,
+ * exeucting the SQL or processing the SQL results.
*/
public List list() throws HibernateException;
@@ -335,6 +394,9 @@
*
* @return The {@link ScrollableResults} representing the matched
* query results.
+ *
+ * @throws HibernateException Indicates a problem either translating the criteria to SQL,
+ * exeucting the SQL or processing the SQL results.
*/
public ScrollableResults scroll() throws HibernateException;
@@ -344,8 +406,12 @@
*
* @param scrollMode Indicates the type of underlying database cursor to
* request.
+ *
* @return The {@link ScrollableResults} representing the matched
* query results.
+ *
+ * @throws HibernateException Indicates a problem either translating the criteria to SQL,
+ * exeucting the SQL or processing the SQL results.
*/
public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException;
@@ -358,4 +424,4 @@
*/
public Object uniqueResult() throws HibernateException;
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -80,7 +80,7 @@
private CacheMode cacheMode;
private FlushMode sessionFlushMode;
private CacheMode sessionCacheMode;
-
+
private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;
@@ -202,6 +202,11 @@
return this;
}
+ public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) {
+ new Subcriteria( this, associationPath, alias, joinType, withClause );
+ return this;
+ }
+
public Criteria createCriteria(String associationPath) {
return createCriteria( associationPath, INNER_JOIN );
}
@@ -218,6 +223,10 @@
return new Subcriteria( this, associationPath, alias, joinType );
}
+ public Criteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause) {
+ return new Subcriteria( this, associationPath, alias, joinType, withClause );
+ }
+
public ResultTransformer getResultTransformer() {
return resultTransformer;
}
@@ -309,7 +318,7 @@
after();
}
}
-
+
public ScrollableResults scroll() {
return scroll( ScrollMode.SCROLL_INSENSITIVE );
}
@@ -338,7 +347,7 @@
getSession().setCacheMode( cacheMode );
}
}
-
+
protected void after() {
if ( sessionFlushMode != null ) {
getSession().setFlushMode( sessionFlushMode );
@@ -349,7 +358,7 @@
sessionCacheMode = null;
}
}
-
+
public boolean isLookupByNaturalKey() {
if ( projection != null ) {
return false;
@@ -374,27 +383,32 @@
private Criteria parent;
private LockMode lockMode;
private int joinType;
+ private Criterion withClause;
-
// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- private Subcriteria(Criteria parent, String path, String alias, int joinType) {
+ private Subcriteria(Criteria parent, String path, String alias, int joinType, Criterion withClause) {
this.alias = alias;
this.path = path;
this.parent = parent;
this.joinType = joinType;
- CriteriaImpl.this.subcriteriaList.add(this);
+ this.withClause = withClause;
+ CriteriaImpl.this.subcriteriaList.add( this );
}
+ private Subcriteria(Criteria parent, String path, String alias, int joinType) {
+ this( parent, path, alias, joinType, null );
+ }
+
private Subcriteria(Criteria parent, String path, int joinType) {
this( parent, path, null, joinType );
}
public String toString() {
- return "Subcriteria(" +
- path + ":" +
- (alias==null ? "" : alias) +
- ')';
+ return "Subcriteria("
+ + path + ":"
+ + (alias==null ? "" : alias)
+ + ')';
}
@@ -429,7 +443,11 @@
return joinType;
}
+ public Criterion getWithClause() {
+ return this.withClause;
+ }
+
// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Criteria add(Criterion expression) {
@@ -451,6 +469,11 @@
return this;
}
+ public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException {
+ new Subcriteria( this, associationPath, alias, joinType, withClause );
+ return this;
+ }
+
public Criteria createCriteria(String associationPath) {
return createCriteria( associationPath, INNER_JOIN );
}
@@ -467,6 +490,10 @@
return new Subcriteria( Subcriteria.this, associationPath, alias, joinType );
}
+ public Criteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException {
+ return new Subcriteria( this, associationPath, alias, joinType, withClause );
+ }
+
public Criteria setCacheable(boolean cacheable) {
CriteriaImpl.this.setCacheable(cacheable);
return this;
@@ -493,8 +520,7 @@
return CriteriaImpl.this.uniqueResult();
}
- public Criteria setFetchMode(String associationPath, FetchMode mode)
- throws HibernateException {
+ public Criteria setFetchMode(String associationPath, FetchMode mode) {
CriteriaImpl.this.setFetchMode( StringHelper.qualify(path, associationPath), mode);
return this;
}
Modified: core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -85,6 +85,7 @@
null,
alias,
JoinFragment.LEFT_OUTER_JOIN,
+ null,
getFactory(),
CollectionHelper.EMPTY_MAP
)
Modified: core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -207,6 +207,10 @@
}
}
+ protected String getWithClause(String path) {
+ return "";
+ }
+
/**
* Add on association (one-to-one, many-to-one, or a collection) to a list
* of associations to be fetched by outerjoin
@@ -235,6 +239,7 @@
aliasedLhsColumns,
subalias,
joinType,
+ getWithClause(path),
getFactory(),
loadQueryInfluencers.getEnabledFilters()
);
Modified: core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -59,6 +59,7 @@
String[] lhsColumns,
String rhsAlias,
int joinType,
+ String withClause,
SessionFactoryImplementor factory,
Map enabledFilters) throws MappingException {
this.joinableType = joinableType;
@@ -68,7 +69,8 @@
this.joinType = joinType;
this.joinable = joinableType.getAssociatedJoinable(factory);
this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory);
- this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters);
+ this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters)
+ + ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" );
this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
}
@@ -188,4 +190,4 @@
joinable.whereJoinFragment(rhsAlias, false, true)
);
}
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -80,6 +80,7 @@
null,
alias,
JoinFragment.LEFT_OUTER_JOIN,
+ null,
getFactory(),
CollectionHelper.EMPTY_MAP
)
Modified: core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -85,6 +85,7 @@
null,
alias,
JoinFragment.LEFT_OUTER_JOIN,
+ null,
getFactory(),
CollectionHelper.EMPTY_MAP
) );
Modified: core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -210,4 +210,8 @@
return "criteria query";
}
+ protected String getWithClause(String path) {
+ return translator.getWithClause(path);
+ }
+
}
Modified: core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -43,6 +43,7 @@
import org.hibernate.QueryException;
import org.hibernate.hql.ast.util.SessionFactoryHelper;
import org.hibernate.criterion.CriteriaQuery;
+import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projection;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.RowSelection;
@@ -77,7 +78,8 @@
private final Map aliasCriteriaMap = new HashMap();
private final Map associationPathCriteriaMap = new LinkedHashMap();
private final Map associationPathJoinTypesMap = new LinkedHashMap();
-
+ private final Map withClauseMap = new HashMap();
+
private final SessionFactoryImplementor sessionFactory;
public CriteriaQueryTranslator(
@@ -169,6 +171,10 @@
// TODO : not so sure this is needed...
throw new QueryException( "duplicate association path: " + wholeAssociationPath );
}
+ if ( crit.getWithClause() != null )
+ {
+ this.withClauseMap.put(wholeAssociationPath, crit.getWithClause());
+ }
}
}
@@ -266,20 +272,6 @@
}
public QueryParameters getQueryParameters() {
- List values = new ArrayList();
- List types = new ArrayList();
- Iterator iter = rootCriteria.iterateExpressionEntries();
- while ( iter.hasNext() ) {
- CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next();
- TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
- for ( int i = 0; i < tv.length; i++ ) {
- values.add( tv[i].getValue() );
- types.add( tv[i].getType() );
- }
- }
- Object[] valueArray = values.toArray();
- Type[] typeArray = ArrayHelper.toTypeArray( types );
-
RowSelection selection = new RowSelection();
selection.setFirstRow( rootCriteria.getFirstResult() );
selection.setMaxRows( rootCriteria.getMaxResults() );
@@ -287,12 +279,14 @@
selection.setFetchSize( rootCriteria.getFetchSize() );
Map lockModes = new HashMap();
- iter = rootCriteria.getLockModes().entrySet().iterator();
+ Iterator iter = rootCriteria.getLockModes().entrySet().iterator();
while ( iter.hasNext() ) {
Map.Entry me = ( Map.Entry ) iter.next();
final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() );
lockModes.put( getSQLAlias( subcriteria ), me.getValue() );
}
+ List values = new ArrayList();
+ List types = new ArrayList();
iter = rootCriteria.iterateSubcriteria();
while ( iter.hasNext() ) {
CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next();
@@ -300,8 +294,31 @@
if ( lm != null ) {
lockModes.put( getSQLAlias( subcriteria ), lm );
}
+ if ( subcriteria.getWithClause() != null )
+ {
+ TypedValue[] tv = subcriteria.getWithClause().getTypedValues( subcriteria, this );
+ for ( int i = 0; i < tv.length; i++ ) {
+ values.add( tv[i].getValue() );
+ types.add( tv[i].getType() );
+ }
+ }
}
+ // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering,
+ // because the lock mode gathering loop now contains join clauses which can contain
+ // parameter bindings (as in the HQL WITH clause).
+ iter = rootCriteria.iterateExpressionEntries();
+ while ( iter.hasNext() ) {
+ CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next();
+ TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
+ for ( int i = 0; i < tv.length; i++ ) {
+ values.add( tv[i].getValue() );
+ types.add( tv[i].getType() );
+ }
+ }
+
+ Object[] valueArray = values.toArray();
+ Type[] typeArray = ArrayHelper.toTypeArray( types );
return new QueryParameters(
typeArray,
valueArray,
@@ -576,4 +593,10 @@
return propertyName;
}
+ public String getWithClause(String path)
+ {
+ final Criterion crit = (Criterion)this.withClauseMap.get(path);
+ return crit == null ? null : crit.toSqlString(getCriteria(path), this);
+ }
+
}
Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/query_criteria.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/query_criteria.xml 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/query_criteria.xml 2009-11-20 05:20:28 UTC (rev 18012)
@@ -196,6 +196,34 @@
Cat kitten = (Cat) map.get("kt");
}]]></programlisting>
+ <para>
+ Additionally you may manipulate the result set using a left outer join:
+ </para>
+ <programlisting><![CDATA[
+ List cats = session.createCriteria( Cat.class )
+ .createAlias("mate", "mt", Criteria.LEFT_JOIN, Restrictions.like("mt.name", "good%") )
+ .addOrder(Order.asc("mt.age"))
+ .list();
+
+ ]]></programlisting>
+
+ <para>
+ This will return all of the <literal>Cat</literal>s with a mate whose name starts with "good"
+ ordered by their mate's age, and all cats who do not have a mate.
+ This is useful when there is a need to order or limit in the database
+ prior to returning complex/large result sets, and removes many instances where
+ multiple queries would have to be performed and the results unioned
+ by java in memory.
+ </para>
+ <para>
+ Without this feature, first all of the cats without a mate would need to be loaded in one query.
+ </para>
+ <para>
+ A second query would need to retreive the cats with mates who's name started with "good" sorted by the mates age.
+ </para>
+ <para>
+ Thirdly, in memory; the lists would need to be joined manually.
+ </para>
</sect1>
<sect1 id="querycriteria-dynamicfetching" revision="1">
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java 2009-11-19 19:45:41 UTC (rev 18011)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/criteria/CriteriaQueryTest.java 2009-11-20 05:20:28 UTC (rev 18012)
@@ -794,5 +794,99 @@
t.commit();
session.close();
}
+
+ public void testAliasJoinCriterion() {
+ Session session = openSession();
+ Transaction t = session.beginTransaction();
+
+ Course courseA = new Course();
+ courseA.setCourseCode("HIB-A");
+ courseA.setDescription("Hibernate Training A");
+ session.persist(courseA);
+
+ Course courseB = new Course();
+ courseB.setCourseCode("HIB-B");
+ courseB.setDescription("Hibernate Training B");
+ session.persist(courseB);
+
+ Student gavin = new Student();
+ gavin.setName("Gavin King");
+ gavin.setStudentNumber(232);
+ gavin.setPreferredCourse(courseA);
+ session.persist(gavin);
+
+ Student leonardo = new Student();
+ leonardo.setName("Leonardo Quijano");
+ leonardo.setStudentNumber(233);
+ leonardo.setPreferredCourse(courseB);
+ session.persist(leonardo);
+
+ Student johnDoe = new Student();
+ johnDoe.setName("John Doe");
+ johnDoe.setStudentNumber(235);
+ johnDoe.setPreferredCourse(null);
+ session.persist(johnDoe);
+
+ // test == on one value exists
+ List result = session.createCriteria( Student.class )
+ .createAlias( "preferredCourse", "pc", Criteria.LEFT_JOIN, Restrictions.eq("pc.courseCode", "HIB-A") )
+ .setProjection( Property.forName("pc.courseCode") )
+ .addOrder(Order.asc("pc.courseCode"))
+ .list();
+
+ assertEquals( 3, result.size() );
+
+ // can't be sure of NULL comparison ordering aside from they should
+ // either come first or last
+ if ( result.get( 0 ) == null ) {
+ assertNull(result.get(1));
+ assertEquals( "HIB-A", result.get(2) );
+ }
+ else {
+ assertNull( result.get(2) );
+ assertNull( result.get(1) );
+ assertEquals( "HIB-A", result.get(0) );
+ }
+
+ // test == on non existent value
+ result = session.createCriteria( Student.class )
+ .createAlias( "preferredCourse", "pc", Criteria.LEFT_JOIN, Restrictions.eq("pc.courseCode", "HIB-R") )
+ .setProjection( Property.forName("pc.courseCode") )
+ .addOrder(Order.asc("pc.courseCode"))
+ .list();
+
+ assertEquals( 3, result.size() );
+ assertNull( result.get(2) );
+ assertNull( result.get(1) );
+ assertNull(result.get(0) );
+
+ // test != on one existing value
+ result = session.createCriteria( Student.class )
+ .createAlias( "preferredCourse", "pc", Criteria.LEFT_JOIN, Restrictions.ne("pc.courseCode", "HIB-A") )
+ .setProjection( Property.forName("pc.courseCode") )
+ .addOrder(Order.asc("pc.courseCode"))
+ .list();
+
+ assertEquals( 3, result.size() );
+ // can't be sure of NULL comparison ordering aside from they should
+ // either come first or last
+ if ( result.get( 0 ) == null ) {
+ assertNull( result.get(1) );
+ assertEquals( "HIB-B", result.get(2) );
+ }
+ else {
+ assertEquals( "HIB-B", result.get(0) );
+ assertNull( result.get(1) );
+ assertNull( result.get(2) );
+ }
+
+ session.delete(gavin);
+ session.delete(leonardo);
+ session.delete(johnDoe);
+ session.delete(courseA);
+ session.delete(courseB);
+ t.commit();
+ session.close();
+ }
}
15 years
Hibernate SVN: r18011 - in sandbox/trunk/new-metadata: src/main/java/org/hibernate/metadata/java and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-11-19 14:45:41 -0500 (Thu, 19 Nov 2009)
New Revision: 18011
Added:
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/AbstractAttributeContainer.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Component.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Hierarchical.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/PluralAttribute.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/SingularAttribute.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Superclass.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularAssociationAttributeMapping.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularBasicAttributeMapping.java
Modified:
sandbox/trunk/new-metadata/build.gradle
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Attribute.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Entity.java
sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/package.html
sandbox/trunk/new-metadata/src/test/java/org/hibernate/metadata/schema/ObjectNameTests.java
Log:
tad more work on this
Modified: sandbox/trunk/new-metadata/build.gradle
===================================================================
--- sandbox/trunk/new-metadata/build.gradle 2009-11-19 16:34:07 UTC (rev 18010)
+++ sandbox/trunk/new-metadata/build.gradle 2009-11-19 19:45:41 UTC (rev 18011)
@@ -12,7 +12,7 @@
version = '1.0.0-SNAPSHOT'
dependencies {
- hibernateVersion = '3.3.2.GA'
+ hibernateVersion = '3.5.0-Beta-2'
slf4jVersion = '1.5.8'
jtaVersion = '1.1'
javassistVersion = '3.9.0.GA'
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/AbstractAttributeContainer.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/AbstractAttributeContainer.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/AbstractAttributeContainer.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,73 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAttributeContainer implements AttributeContainer {
+ private final Class javaType;
+ private LinkedHashSet attributeSet = new LinkedHashSet();
+ private HashMap attributeMap = new HashMap();
+
+ protected AbstractAttributeContainer(Class javaType) {
+ this.javaType = javaType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class getJavaType() {
+ return javaType;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set getAttributes() {
+ return Collections.unmodifiableSet( attributeSet );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Attribute getAttribute(String name) {
+ return (Attribute) attributeMap.get( name );
+ }
+
+ public void addAttribute(Attribute attribute) {
+ // todo : how to best "secure" this?
+ if ( attributeMap.put( attribute.getName(), attribute ) != null ) {
+ throw new IllegalArgumentException( "Attrtibute with name [" + attribute.getName() + "] already registered" );
+ }
+ attributeSet.add( attribute );
+ }
+}
Modified: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Attribute.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Attribute.java 2009-11-19 16:34:07 UTC (rev 18010)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Attribute.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -23,12 +23,40 @@
*/
package org.hibernate.metadata.java;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
/**
- * TODO : javadoc
+ * Most basic contract of an attribute
*
* @author Steve Ebersole
*/
public interface Attribute {
+ /**
+ * Retrieve the attribute name.
+ *
+ * @return The attribute name.
+ */
public String getName();
+
+ /**
+ * Retrieve the declaring container for this attribute (entity/component).
+ *
+ * @return The attribute container.
+ */
public AttributeContainer getAttributeContainer();
+
+ /**
+ * Is this attribute singular (i.e. castable to {@link SingularAttribute})? The other alternative
+ * is {@link PluralAttribute}).
+ *
+ * @return True if the castable to {@link SingularAttribute}; false if castable to {@link PluralAttribute}).
+ */
+ public boolean isSingular();
+
+ public Field getField();
+
+ public Method getGetterMethod();
+
+ public Method getSetterMethod();
}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Component.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Component.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Component.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+/**
+ * TODO : javadoc
+ * <p/>
+ * NOTE : Components are not currently really hierarchical. But that is a feature I want to add.
+ *
+ * @author Steve Ebersole
+ */
+public class Component extends AbstractAttributeContainer implements Hierarchical {
+ private final Hierarchical superType;
+
+ public Component(Class javaType, Hierarchical superType) {
+ super( javaType );
+ this.superType = superType;
+ }
+
+ public Hierarchical getSuperTye() {
+ return superType;
+ }
+
+ public TypeNature getNature() {
+ return TypeNature.COMPONENT;
+ }
+}
Modified: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Entity.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Entity.java 2009-11-19 16:34:07 UTC (rev 18010)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Entity.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -28,5 +28,19 @@
*
* @author Steve Ebersole
*/
-public class Entity {
+public class Entity extends AbstractAttributeContainer implements Hierarchical {
+ private final Hierarchical superType;
+
+ public Entity(Class javaType, Hierarchical superType) {
+ super( javaType );
+ this.superType = superType;
+ }
+
+ public Hierarchical getSuperTye() {
+ return superType;
+ }
+
+ public TypeNature getNature() {
+ return TypeNature.ENTITY;
+ }
}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Hierarchical.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Hierarchical.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Hierarchical.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,33 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface Hierarchical extends AttributeContainer {
+ public Hierarchical getSuperTye();
+}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/PluralAttribute.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/PluralAttribute.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/PluralAttribute.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,34 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface PluralAttribute {
+ public Class getCollectionJavaType();
+ public Class getCollectionElementType();
+}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/SingularAttribute.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/SingularAttribute.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/SingularAttribute.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,33 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+/**
+ * A single valued (non-collection) attribute
+ *
+ * @author Steve Ebersole
+ */
+public interface SingularAttribute extends Attribute {
+ public Type getSingularAttributeType();
+}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Superclass.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Superclass.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/Superclass.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.java;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Superclass extends AbstractAttributeContainer implements Hierarchical {
+ private final Hierarchical superType;
+
+ public Superclass(Class javaType, Hierarchical superType) {
+ super( javaType );
+ this.superType = superType;
+ }
+
+ public Hierarchical getSuperTye() {
+ return superType;
+ }
+
+ public TypeNature getNature() {
+ return TypeNature.SUPERCLASS;
+ }
+}
Modified: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/package.html
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/package.html 2009-11-19 16:34:07 UTC (rev 18010)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/java/package.html 2009-11-19 19:45:41 UTC (rev 18011)
@@ -25,7 +25,9 @@
<html>
<body>
<p>
- This package defines metadata modeling of a Java domain model.
+ This package defines metadata modeling of a Java domain model. Specifically note that
+ this package does not in any way attempt to encapsulate data modeling information such
+ cardinality.
</p>
</body>
</html>
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularAssociationAttributeMapping.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularAssociationAttributeMapping.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularAssociationAttributeMapping.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,86 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.mapping;
+
+import org.hibernate.metadata.java.Attribute;
+import org.hibernate.metadata.java.SingularAttribute;
+import org.hibernate.metadata.schema.ForeignKey;
+import org.hibernate.metadata.schema.Value;
+
+/**
+ * Defines the mapping of <tt>one-to-one</tt> or <tt>many-to-one</tt> association.
+ *
+ * @author Steve Ebersole
+ */
+public class SingularAssociationAttributeMapping implements AttributeMapping {
+ public static class Cardinality {
+ public static final Cardinality ONE_TO_ONE = new Cardinality( "1-1" );
+ public static final Cardinality MANY_TO_ONE = new Cardinality( "m-1" );
+
+ private final String name;
+
+ private Cardinality(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ }
+
+ private final SingularAttribute attribute;
+ private final ForeignKey foreignKey;
+ private final Cardinality cardinality;
+
+ public SingularAssociationAttributeMapping(
+ SingularAttribute attribute,
+ ForeignKey foreignKey,
+ Cardinality cardinality) {
+ this.attribute = attribute;
+ this.foreignKey = foreignKey;
+ this.cardinality = cardinality;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Attribute getAttribute() {
+ return attribute;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Value[] getColumns() {
+ return (Value[]) getForeignKey().getSourceColumns().toArray( new Value[getForeignKey().getSourceColumns().size()] );
+ }
+
+ public ForeignKey getForeignKey() {
+ return foreignKey;
+ }
+
+ public Cardinality getCardinality() {
+ return cardinality;
+ }
+}
Added: sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularBasicAttributeMapping.java
===================================================================
--- sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularBasicAttributeMapping.java (rev 0)
+++ sandbox/trunk/new-metadata/src/main/java/org/hibernate/metadata/mapping/SingularBasicAttributeMapping.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.metadata.mapping;
+
+import org.hibernate.metadata.java.Attribute;
+import org.hibernate.metadata.java.SingularAttribute;
+import org.hibernate.metadata.schema.Value;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class SingularBasicAttributeMapping implements AttributeMapping {
+ private final SingularAttribute attribute;
+ private final Value[] columns;
+
+ public SingularBasicAttributeMapping(SingularAttribute attribute, Value[] columns) {
+ this.attribute = attribute;
+ this.columns = columns;
+ }
+
+ public Attribute getAttribute() {
+ return attribute;
+ }
+
+ public Value[] getColumns() {
+ return columns;
+ }
+}
Modified: sandbox/trunk/new-metadata/src/test/java/org/hibernate/metadata/schema/ObjectNameTests.java
===================================================================
--- sandbox/trunk/new-metadata/src/test/java/org/hibernate/metadata/schema/ObjectNameTests.java 2009-11-19 16:34:07 UTC (rev 18010)
+++ sandbox/trunk/new-metadata/src/test/java/org/hibernate/metadata/schema/ObjectNameTests.java 2009-11-19 19:45:41 UTC (rev 18011)
@@ -50,5 +50,7 @@
public void testIdentifierBuilding() {
ObjectName on = new ObjectName( "schema", "catalog", "name" );
assertEquals( "schema.catalog.name", on.getIdentifier() );
+ on = new ObjectName( "schema", null, "name" );
+ assertEquals( "schema.name", on.getIdentifier() );
}
}
15 years
Hibernate SVN: r18010 - search/trunk/src/test/java/org/hibernate/search/test/id/providedId.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-11-19 11:34:07 -0500 (Thu, 19 Nov 2009)
New Revision: 18010
Modified:
search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java
Log:
rolling back failure on the ProvidedIdTest. Need to remove the hibernate core use and simulate what infinispan is doing somehow.
Modified: search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java 2009-11-19 08:51:35 UTC (rev 18009)
+++ search/trunk/src/test/java/org/hibernate/search/test/id/providedId/ProvidedIdPerson.java 2009-11-19 16:34:07 UTC (rev 18010)
@@ -29,9 +29,12 @@
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.ProvidedId;
import org.hibernate.search.annotations.Store;
+import org.hibernate.search.annotations.FieldBridge;
+import org.hibernate.search.bridge.builtin.LongBridge;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
import java.io.Serializable;
@@ -39,10 +42,11 @@
* @author Navin Surtani
*/
@Entity
-@ProvidedId
+@ProvidedId(bridge = @FieldBridge(impl = LongBridge.class) )
@Indexed
public class ProvidedIdPerson implements Serializable {
+ @Id
@GeneratedValue
private long id;
15 years
Hibernate SVN: r18009 - in validator/trunk: hibernate-validator-annotation-processor and 12 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-11-19 03:51:35 -0500 (Thu, 19 Nov 2009)
New Revision: 18009
Added:
validator/trunk/hibernate-validator-annotation-processor/
validator/trunk/hibernate-validator-annotation-processor/pom.xml
validator/trunk/hibernate-validator-annotation-processor/src/
validator/trunk/hibernate-validator-annotation-processor/src/main/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/
validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
validator/trunk/hibernate-validator-annotation-processor/src/main/resources/
validator/trunk/hibernate-validator-annotation-processor/src/test/
validator/trunk/hibernate-validator-annotation-processor/src/test/java/
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/
validator/trunk/hibernate-validator-annotation-processor/src/test/java/org/hibernate/validator/ap/
Modified:
validator/trunk/pom.xml
Log:
HV-269 created project shell for the annotation processor
Added: validator/trunk/hibernate-validator-annotation-processor/pom.xml
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/pom.xml (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/pom.xml 2009-11-19 08:51:35 UTC (rev 18009)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>hibernate-validator-parent</artifactId>
+ <groupId>org.hibernate</groupId>
+ <version>4.0.3-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator-annotation-processor</artifactId>
+ <name>Hibernate Validator Annotation Processor</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-validator</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.8</version>
+ <classifier>jdk15</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java
===================================================================
--- validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java (rev 0)
+++ validator/trunk/hibernate-validator-annotation-processor/src/main/java/org/hibernate/validator/ap/ConstraintValidationProcessor.java 2009-11-19 08:51:35 UTC (rev 18009)
@@ -0,0 +1,68 @@
+// $Id: JPAMetaModelEntityProcessor.java 17946 2009-11-06 18:23:48Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.hibernate.validator.ap;
+
+
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import static javax.lang.model.SourceVersion.RELEASE_6;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import javax.tools.Diagnostic;
+
+
+/**
+ * Annotation processor for validating Bean Validation constraints.
+ *
+ * @author Hardy Ferentschik
+ */
+@SupportedAnnotationTypes("*")
+@SupportedSourceVersion(RELEASE_6)
+public class ConstraintValidationProcessor extends AbstractProcessor {
+ private static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE;
+ private Messager messager;
+
+ public void init(ProcessingEnvironment env) {
+ super.init( env );
+ messager = env.getMessager();
+ messager.printMessage( Diagnostic.Kind.NOTE, "Init Processor " + this );
+ }
+
+ @Override
+ public boolean process(final Set<? extends TypeElement> annotations,
+ final RoundEnvironment roundEnvironment) {
+
+ if ( roundEnvironment.processingOver() ) {
+ messager.printMessage( Diagnostic.Kind.NOTE, "Last processing round." );
+ return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
+ }
+
+ Set<? extends Element> elements = roundEnvironment.getRootElements();
+ for ( Element element : elements ) {
+ messager.printMessage( Diagnostic.Kind.NOTE, "Processing " + element.toString() );
+ }
+
+ return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
+ }
+}
Modified: validator/trunk/pom.xml
===================================================================
--- validator/trunk/pom.xml 2009-11-19 01:34:35 UTC (rev 18008)
+++ validator/trunk/pom.xml 2009-11-19 08:51:35 UTC (rev 18009)
@@ -40,6 +40,7 @@
<module>hibernate-validator-archetype</module>
<module>hibernate-validator-legacy</module>
<module>hibernate-validator-tck-runner</module>
+ <module>hibernate-validator-annotation-processor</module>
</modules>
<dependencyManagement>
15 years
Hibernate SVN: r18008 - in core/trunk/entitymanager/src: test/java/org/hibernate/ejb/criteria/components and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-11-18 20:34:35 -0500 (Wed, 18 Nov 2009)
New Revision: 18008
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/CastFunction.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/LocateFunction.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/ParameterizedFunctionExpression.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/SubstringFunction.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/TrimFunction.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java
core/trunk/entitymanager/src/test/resources/log4j.properties
Log:
HHH-4586 - Jpa2.0 Criteria API lower function missing parameter
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/CastFunction.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/CastFunction.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/CastFunction.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -25,6 +25,7 @@
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.ExpressionImpl;
/**
@@ -57,4 +58,9 @@
Helper.possibleParameter( getCastSource(), registry );
}
+ public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
+ // HHH-4590
+ // todo : how to handle these, espeically if in the select...
+ return super.render( renderingContext );
+ }
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/LocateFunction.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/LocateFunction.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/LocateFunction.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -27,7 +27,9 @@
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
+import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models the ANSI SQL <tt>LOCATE</tt> function.
@@ -95,4 +97,19 @@
Helper.possibleParameter( getStart(), registry );
Helper.possibleParameter( getString(), registry );
}
+
+ @Override
+ public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append( "locate(" )
+ .append( ( (ExpressionImplementor) getPattern() ).render( renderingContext ) )
+ .append( ',' )
+ .append( ( (ExpressionImplementor) getString() ).render( renderingContext ) );
+ if ( getStart() != null ) {
+ buffer.append( ',' )
+ .append( ( (ExpressionImplementor) getStart() ).render( renderingContext ) );
+ }
+ buffer.append( ')' );
+ return buffer.toString();
+ }
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/ParameterizedFunctionExpression.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/ParameterizedFunctionExpression.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/ParameterizedFunctionExpression.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -30,7 +30,9 @@
import org.hibernate.ejb.criteria.ParameterContainer;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
+import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Support for functions with parameters.
@@ -86,4 +88,15 @@
}
}
+ @Override
+ public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append( getFunctionName() )
+ .append( '(' );
+ for ( Expression argument : argumentExpressions ) {
+ buffer.append( ( (ExpressionImplementor) argument ).render( renderingContext ) );
+ }
+ buffer.append( ')' );
+ return buffer.toString();
+ }
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/SubstringFunction.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/SubstringFunction.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/SubstringFunction.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -27,7 +27,9 @@
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
+import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models the ANSI SQL <tt>SUBSTRING</tt> function.
@@ -102,4 +104,17 @@
Helper.possibleParameter( getValue(), registry );
}
+ public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append( "substring(" )
+ .append( ( (ExpressionImplementor) getValue() ).render( renderingContext ) )
+ .append( ',' )
+ .append( ( (ExpressionImplementor) getStart() ).render( renderingContext ) );
+ if ( getLength() != null ) {
+ buffer.append( ',' )
+ .append( ( (ExpressionImplementor) getLength() ).render( renderingContext ) );
+ }
+ buffer.append( ')' );
+ return buffer.toString();
+ }
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/TrimFunction.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/TrimFunction.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/function/TrimFunction.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -27,7 +27,9 @@
import javax.persistence.criteria.CriteriaBuilder.Trimspec;
import org.hibernate.ejb.criteria.ParameterRegistry;
import org.hibernate.ejb.criteria.CriteriaBuilderImpl;
+import org.hibernate.ejb.criteria.CriteriaQueryCompiler;
import org.hibernate.ejb.criteria.expression.LiteralExpression;
+import org.hibernate.ejb.criteria.expression.ExpressionImplementor;
/**
* Models the ANSI SQL <tt>TRIM</tt> function.
@@ -110,4 +112,16 @@
Helper.possibleParameter( getTrimSource(), registry );
}
+ @Override
+ public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
+ return new StringBuilder()
+ .append( "trim(" )
+ .append( trimspec.name() )
+ .append( ' ' )
+ .append( ( (ExpressionImplementor) trimCharacter ).render( renderingContext ) )
+ .append( " from " )
+ .append( ( (ExpressionImplementor) trimSource ).render( renderingContext ) )
+ .append( ')' )
+ .toString();
+ }
}
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java 2009-11-19 01:34:35 UTC (rev 18008)
@@ -28,6 +28,7 @@
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Expression;
import org.hibernate.ejb.test.TestCase;
@@ -65,4 +66,23 @@
em.getTransaction().commit();
em.close();
}
+
+ public void testParameterizedFunctions() {
+ // HHH-4586
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ // lower
+ CriteriaQuery<Client> cq = cb.createQuery( Client.class );
+ Root<Client> root = cq.from( Client.class );
+ cq.where( cb.equal( cb.lower( root.get( Client_.name ).get( Name_.lastName ) ),"test" ) );
+ em.createQuery( cq ).getResultList();
+ // upper
+ cq = cb.createQuery( Client.class );
+ root = cq.from( Client.class );
+ cq.where( cb.equal( cb.upper( root.get( Client_.name ).get( Name_.lastName ) ),"test" ) );
+ em.createQuery( cq ).getResultList();
+ em.getTransaction().commit();
+ em.close();
+ }
}
Modified: core/trunk/entitymanager/src/test/resources/log4j.properties
===================================================================
--- core/trunk/entitymanager/src/test/resources/log4j.properties 2009-11-18 22:13:03 UTC (rev 18007)
+++ core/trunk/entitymanager/src/test/resources/log4j.properties 2009-11-19 01:34:35 UTC (rev 18008)
@@ -35,7 +35,7 @@
### log JDBC bind parameters ###
#log4j.logger.org.hibernate.type=info
-log4j.logger.org.hibernate.type=debug
+log4j.logger.org.hibernate.type=trace
### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug
15 years
Hibernate SVN: r18007 - in core/trunk/entitymanager/src: test/java/org/hibernate/ejb/criteria and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-11-18 17:13:03 -0500 (Wed, 18 Nov 2009)
New Revision: 18007
Added:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Client.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Name.java
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/FromImpl.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/JoinImpl.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Address.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Flower.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/FoodItem.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Fridge.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Garden.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/House.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Person.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Room.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java
Log:
HHH-4581 - Embedded objects in criteria API does not work
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/FromImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/FromImpl.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/FromImpl.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -47,6 +47,7 @@
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.PluralAttribute;
+import javax.persistence.metamodel.Bindable;
import javax.persistence.metamodel.PluralAttribute.CollectionType;
import javax.persistence.metamodel.Type.PersistenceType;
@@ -61,6 +62,10 @@
public abstract class FromImpl<Z,X> extends PathImpl<X> implements From<Z,X>, TableExpressionMapper {
public static final JoinType DEFAULT_JOIN_TYPE = JoinType.INNER;
+ private final Expression<Class<? extends X>> typeExpression;
+ private Set<Join<X, ?>> joins;
+ private Set<Fetch<X, ?>> fetches;
+
/**
* Helper contract used to define who/what keeps track of joins and fetches made from this <tt>FROM</tt>.
*/
@@ -71,10 +76,6 @@
public From<?, X> getCorrelationParent();
}
- private final Expression<Class<? extends X>> type;
- private Set<Join<X, ?>> joins;
- private Set<Fetch<X, ?>> fetches;
-
private JoinScope<X> joinScope = new JoinScope<X>() {
public void addJoin(Join<X, ?> join) {
if ( joins == null ) {
@@ -108,7 +109,7 @@
@SuppressWarnings({ "unchecked" })
protected FromImpl(CriteriaBuilderImpl criteriaBuilder, EntityType<X> entityType) {
super( criteriaBuilder, entityType.getBindableJavaType(), null, null, entityType );
- this.type = new EntityTypeExpression( criteriaBuilder, entityType.getBindableJavaType() );
+ this.typeExpression = new EntityTypeExpression( criteriaBuilder, entityType.getBindableJavaType() );
}
/**
@@ -126,9 +127,9 @@
Class<X> javaType,
PathImpl<Z> origin,
Attribute<? super Z, ?> attribute,
- ManagedType<X> model) {
+ Bindable<X> model) {
super( criteriaBuilder, javaType, origin, attribute, model );
- this.type = new EntityTypeExpression( criteriaBuilder, model.getJavaType() );
+ this.typeExpression = new EntityTypeExpression( criteriaBuilder, model.getBindableJavaType() );
}
protected void defineJoinScope(JoinScope<X> joinScope) {
@@ -137,7 +138,7 @@
@Override
public Expression<Class<? extends X>> type() {
- return type;
+ return typeExpression;
}
/**
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/JoinImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/JoinImpl.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/JoinImpl.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -27,6 +27,9 @@
import javax.persistence.criteria.JoinType;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.Bindable;
+import javax.persistence.metamodel.SingularAttribute;
+import javax.persistence.metamodel.EmbeddableType;
/**
* Models a non-collection property join.
@@ -56,7 +59,9 @@
javaType,
lhs,
joinProperty,
- criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType )
+ ( Bindable<X> ) ( Attribute.PersistentAttributeType.EMBEDDED == joinProperty.getPersistentAttributeType()
+ ? joinProperty
+ : criteriaBuilder.getEntityManagerFactory().getMetamodel().managedType( javaType ))
);
this.managedType = getManagedType();
this.joinType = joinType;
@@ -64,7 +69,10 @@
@SuppressWarnings({ "unchecked" })
protected ManagedType<X> getManagedType() {
- return (ManagedType<X>) getModel();
+ Bindable<X> model = getModel();
+ return Bindable.BindableType.ENTITY_TYPE == model.getBindableType()
+ ? (ManagedType<X>) model
+ : (EmbeddableType<X>) ( (SingularAttribute) model ).getType();
}
/**
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Client.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Client.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Client.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.criteria.components;
+
+import java.io.Serializable;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * The client domain entity
+ *
+ */
+@Entity
+public class Client implements Serializable {
+ private int id;
+ private Name name;
+
+ public Client() {
+ }
+
+ public Client(int id, Name name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Client(int id, String firstName, String lastName) {
+ this( id, new Name( firstName, lastName ) );
+ }
+
+ @Id
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Embedded
+ public Name getName() {
+ return name;
+ }
+
+ public void setName(Name name) {
+ this.name = name;
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/ComponentCriteriaTest.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -0,0 +1,68 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.criteria.components;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.hibernate.ejb.test.TestCase;
+
+/**
+ *
+ * @author alan.oleary
+ */
+public class ComponentCriteriaTest extends TestCase {
+ public Class[] getAnnotatedClasses() {
+ return new Class[] { Client.class };
+ }
+
+ public void testEmbeddableInPath() {
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ Client client = new Client( 111, "steve", "ebersole" );
+ em.persist(client);
+ em.getTransaction().commit();
+ em.close();
+
+ em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ CriteriaQuery<Client> cq = cb.createQuery(Client.class);
+ Root<Client> root = cq.from(Client.class);
+ cq.where(cb.equal(root.get("name").get("firstName"), client.getName().getFirstName()));
+ List<Client> list = em.createQuery(cq).getResultList();
+ assertEquals(1, list.size());
+ em.getTransaction().commit();
+ em.close();
+
+ em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ em.createQuery( "delete Client" ).executeUpdate();
+ em.getTransaction().commit();
+ em.close();
+ }
+}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Name.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Name.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/components/Name.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.criteria.components;
+
+import java.io.Serializable;
+import javax.persistence.Embeddable;
+import javax.persistence.Column;
+
+/**
+ * The name component
+ *
+ * @author alan.oleary
+ */
+@Embeddable
+public class Name implements Serializable {
+ private static final long serialVersionUID = 8381969086665589013L;
+
+ private String firstName;
+ private String lastName;
+
+ public Name() {
+ }
+
+ public Name(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ @Column(name = "FIRST_NAME", nullable = false)
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ @Column(name = "LAST_NAME", nullable = false)
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
\ No newline at end of file
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Address.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Address.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Address.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import javax.persistence.Embeddable;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Flower.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Flower.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Flower.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import javax.persistence.Entity;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/FoodItem.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/FoodItem.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/FoodItem.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import javax.persistence.Entity;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Fridge.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Fridge.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Fridge.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import javax.persistence.Entity;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Garden.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Garden.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Garden.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,6 +1,28 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
-import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import javax.persistence.Entity;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/House.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/House.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/House.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import java.io.Serializable;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/MetadataTest.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import java.util.Set;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Person.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Person.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Person.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import java.io.Serializable;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Room.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Room.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/Room.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
import java.math.BigDecimal;
Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java 2009-11-18 21:02:19 UTC (rev 18006)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/metadata/SubThing.java 2009-11-18 22:13:03 UTC (rev 18007)
@@ -1,3 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.metadata;
/**
15 years
Hibernate SVN: r18006 - in core/trunk: core/src/main/java/org/hibernate/hql/ast/tree and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-11-18 16:02:19 -0500 (Wed, 18 Nov 2009)
New Revision: 18006
Added:
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ComponentJoin.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/ql/
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/ql/ComponentJoinsTest.java
Modified:
core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java
Log:
HHH-4584 - Query Language needs to support joins on embedded values
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java 2009-11-18 16:56:13 UTC (rev 18005)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -69,6 +69,7 @@
import org.hibernate.hql.ast.tree.UpdateStatement;
import org.hibernate.hql.ast.tree.OperatorNode;
import org.hibernate.hql.ast.tree.ParameterContainer;
+import org.hibernate.hql.ast.tree.FromElementFactory;
import org.hibernate.hql.ast.util.ASTPrinter;
import org.hibernate.hql.ast.util.ASTUtil;
import org.hibernate.hql.ast.util.AliasGenerator;
@@ -92,6 +93,7 @@
import org.hibernate.type.Type;
import org.hibernate.type.VersionType;
import org.hibernate.type.DbTimestampType;
+import org.hibernate.type.ComponentType;
import org.hibernate.usertype.UserVersionType;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.StringHelper;
@@ -362,14 +364,29 @@
// Generate an explicit join for the root dot node. The implied joins will be collected and passed up
// to the root dot node.
dot.resolve( true, false, alias == null ? null : alias.getText() );
- FromElement fromElement = dot.getImpliedJoin();
- fromElement.setAllPropertyFetch(propertyFetch!=null);
- if ( with != null ) {
- if ( fetch ) {
- throw new SemanticException( "with-clause not allowed on fetched associations; use filters" );
+ final FromElement fromElement;
+ if ( dot.getDataType() != null && dot.getDataType().isComponentType() ) {
+ FromElementFactory factory = new FromElementFactory(
+ getCurrentFromClause(),
+ dot.getLhs().getFromElement(),
+ dot.getPropertyPath(),
+ alias == null ? null : alias.getText(),
+ null,
+ false
+ );
+ fromElement = factory.createComponentJoin( (ComponentType) dot.getDataType() );
+ }
+ else {
+ fromElement = dot.getImpliedJoin();
+ fromElement.setAllPropertyFetch( propertyFetch != null );
+
+ if ( with != null ) {
+ if ( fetch ) {
+ throw new SemanticException( "with-clause not allowed on fetched associations; use filters" );
+ }
+ handleWithFragment( fromElement, with );
}
- handleWithFragment( fromElement, with );
}
if ( log.isDebugEnabled() ) {
Added: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ComponentJoin.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ComponentJoin.java (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ComponentJoin.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -0,0 +1,181 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.hql.ast.tree;
+
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
+import org.hibernate.hql.NameGenerator;
+
+/**
+ * Models an explicit join terminating at a component value (e.g. <tt>... from Person p join p.name as n ...</tt>)
+ *
+ * @author Steve Ebersole
+ */
+public class ComponentJoin extends FromElement {
+ private final String componentPath;
+ private final ComponentType componentType;
+
+ private final String componentProperty;
+ private final String columns;
+
+ public ComponentJoin(
+ FromClause fromClause,
+ FromElement origin,
+ String alias,
+ String componentPath,
+ ComponentType componentType) {
+ super( fromClause, origin, alias );
+ this.componentPath = componentPath;
+ this.componentType = componentType;
+ this.componentProperty = StringHelper.unqualify( componentPath );
+ fromClause.addJoinByPathMap( componentPath, this );
+ initializeComponentJoin( new ComponentFromElementType( this ) );
+
+ final String[] cols = origin.getPropertyMapping( "" ).toColumns( getTableAlias(), componentProperty );
+ StringBuffer buf = new StringBuffer();
+ for ( int j = 0; j < cols.length; j++ ) {
+ final String column = cols[j];
+ if ( j > 0 ) {
+ buf.append( ", " );
+ }
+ buf.append( column );
+ }
+ this.columns = buf.toString();
+ }
+
+ public String getComponentPath() {
+ return componentPath;
+ }
+
+ public String getComponentProperty() {
+ return componentProperty;
+ }
+
+ public ComponentType getComponentType() {
+ return componentType;
+ }
+
+
+ public Type getDataType() {
+ return getComponentType();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getIdentityColumn() {
+ // used to "resolve" the IdentNode when our alias is encountered *by itself* in the query; so
+ // here we use the component
+ // NOTE : ^^ is true *except for* when encountered by itself in the SELECT clause. That gets
+ // routed through org.hibernate.hql.ast.tree.ComponentJoin.ComponentFromElementType.renderScalarIdentifierSelect()
+ // which we also override to account for
+ return columns;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getDisplayText() {
+ return "ComponentJoin{path=" + getComponentPath() + ", type=" + componentType.getReturnedClass() + "}";
+ }
+
+ public class ComponentFromElementType extends FromElementType {
+ private final PropertyMapping propertyMapping = new ComponentPropertyMapping();
+
+ public ComponentFromElementType(FromElement fromElement) {
+ super( fromElement );
+ }
+
+ public Type getDataType() {
+ return getComponentType();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public QueryableCollection getQueryableCollection() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyMapping getPropertyMapping(String propertyName) {
+ return propertyMapping;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Type getPropertyType(String propertyName, String propertyPath) {
+ int index = getComponentType().getPropertyIndex( propertyName );
+ return getComponentType().getSubtypes()[index];
+ }
+
+ public String renderScalarIdentifierSelect(int i) {
+ String[] cols = getBasePropertyMapping().toColumns( getTableAlias(), getComponentProperty() );
+ StringBuffer buf = new StringBuffer();
+ // For property references generate <tablealias>.<columnname> as <projectionalias>
+ for ( int j = 0; j < cols.length; j++ ) {
+ final String column = cols[j];
+ if ( j > 0 ) {
+ buf.append( ", " );
+ }
+ buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, j ) );
+ }
+ return buf.toString();
+ }
+ }
+
+ protected PropertyMapping getBasePropertyMapping() {
+ return getOrigin().getPropertyMapping( "" );
+ }
+
+ private final class ComponentPropertyMapping implements PropertyMapping {
+ public Type getType() {
+ return getComponentType();
+ }
+
+ public Type toType(String propertyName) throws QueryException {
+ return getBasePropertyMapping().toType( getPropertyPath( propertyName ) );
+ }
+
+ protected String getPropertyPath(String propertyName) {
+ return getComponentPath() + '.' + propertyName;
+ }
+
+ public String[] toColumns(String alias, String propertyName) throws QueryException {
+ return getBasePropertyMapping().toColumns( alias, getPropertyPath( propertyName ) );
+ }
+
+ public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
+ return getBasePropertyMapping().toColumns( getPropertyPath( propertyName ) );
+ }
+ }
+}
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java 2009-11-18 16:56:13 UTC (rev 18005)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -90,6 +90,30 @@
public FromElement() {
}
+ /**
+ * Constructor form used to initialize {@link ComponentJoin}
+ *
+ * @param fromClause The FROM clause to which this element belongs
+ * @param origin The origin (LHS) of this element
+ * @param alias The alias applied to this element
+ */
+ protected FromElement(
+ FromClause fromClause,
+ FromElement origin,
+ String alias) {
+ this.fromClause = fromClause;
+ this.origin = origin;
+ this.classAlias = alias;
+ this.tableAlias = origin.getTableAlias();
+ super.initialize( fromClause.getWalker() );
+ }
+
+ protected void initializeComponentJoin(FromElementType elementType) {
+ this.elementType = elementType;
+ fromClause.registerFromElement( this );
+ initialized = true;
+ }
+
public String getCollectionSuffix() {
return elementType.getCollectionSuffix();
}
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java 2009-11-18 16:56:13 UTC (rev 18005)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -39,6 +39,7 @@
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
+import org.hibernate.type.ComponentType;
import org.hibernate.util.StringHelper;
import antlr.ASTFactory;
@@ -53,7 +54,7 @@
*
* @author josh
*/
-class FromElementFactory implements SqlTokenTypes {
+public class FromElementFactory implements SqlTokenTypes {
private static final Logger log = LoggerFactory.getLogger( FromElementFactory.class );
@@ -295,6 +296,12 @@
return elem;
}
+ public FromElement createComponentJoin(ComponentType type) {
+ // need to create a "place holder" from-element that can store the component/alias for this
+ // component join
+ return new ComponentJoin( fromClause, origin, classAlias, path, type );
+ }
+
FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
FromElement elem;
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java 2009-11-18 16:56:13 UTC (rev 18005)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -74,6 +74,10 @@
}
}
+ protected FromElementType(FromElement fromElement) {
+ this.fromElement = fromElement;
+ }
+
private String getTableAlias() {
return fromElement.getTableAlias();
}
Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/ql/ComponentJoinsTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/ql/ComponentJoinsTest.java (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/ql/ComponentJoinsTest.java 2009-11-18 21:02:19 UTC (rev 18006)
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.ejb.test.ql;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.ejb.test.TestCase;
+import org.hibernate.ejb.criteria.components.Client;
+
+/**
+ * Tests related to specifying joins on components (embedded values).
+ *
+ * @author Steve Ebersole
+ */
+public class ComponentJoinsTest extends TestCase {
+ public Class[] getAnnotatedClasses() {
+ return new Class[] { Client.class };
+ }
+
+ public void testComponentJoins() {
+ // Just checking proper query construction and syntax checking via database query parser...
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ // use it in WHERE
+ em.createQuery( "select c from Client c join c.name as n where n.lastName like '%'" ).getResultList();
+ // use it in SELECT
+ em.createQuery( "select n.lastName from Client c join c.name as n" ).getResultList();
+ em.createQuery( "select n from Client c join c.name as n" ).getResultList();
+ // use it in ORDER BY
+ em.createQuery( "select n from Client c join c.name as n order by n.lastName" ).getResultList();
+ em.createQuery( "select n from Client c join c.name as n order by c" ).getResultList();
+ em.createQuery( "select n from Client c join c.name as n order by n" ).getResultList();
+ em.getTransaction().commit();
+ em.close();
+ }
+}
15 years
Hibernate SVN: r18005 - in core/trunk/cache-infinispan: src/main/java/org/hibernate/cache/infinispan and 15 other directories.
by hibernate-commits@lists.jboss.org
Author: galder.zamarreno(a)jboss.com
Date: 2009-11-18 11:56:13 -0500 (Wed, 18 Nov 2009)
New Revision: 18005
Added:
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java
Removed:
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/AbstractDualNodeTestCase.java
Modified:
core/trunk/cache-infinispan/pom.xml
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/JndiInfinispanRegionFactory.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/ReadOnlyAccess.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseRegion.java
core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheHelper.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicReadOnlyTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/ClassLoaderTestDAO.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/IsolatedClassLoaderTest.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeConnectionProviderImpl.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionManagerImpl.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTransactionManagerLookup.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/SessionRefreshTestCase.java
core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionImpl.java
core/trunk/cache-infinispan/src/test/resources/hibernate.properties
Log:
[HHH-4520] (Infinispan second level cache integration can cache stale collection data) Ported fix. testManyUsers has been disabled while ISPN-277 gets fixed. Finally, Infinispan version has been upgraded to 4.0.0.CR2.
Modified: core/trunk/cache-infinispan/pom.xml
===================================================================
--- core/trunk/cache-infinispan/pom.xml 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/pom.xml 2009-11-18 16:56:13 UTC (rev 18005)
@@ -17,7 +17,7 @@
<description>Integration of Hibernate with Infinispan</description>
<properties>
- <version.infinispan>4.0.0-SNAPSHOT</version.infinispan>
+ <version.infinispan>4.0.0.CR2</version.infinispan>
<version.hsqldb>1.8.0.2</version.hsqldb>
<version.cglib>2.2</version.cglib>
<version.javassist>3.4.GA</version.javassist>
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/InfinispanRegionFactory.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -32,8 +32,8 @@
import org.infinispan.config.Configuration;
import org.infinispan.manager.CacheManager;
import org.infinispan.manager.DefaultCacheManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* A {@link RegionFactory} for <a href="http://www.jboss.org/infinispan">Infinispan</a>-backed cache
@@ -44,13 +44,13 @@
* @since 3.5
*/
public class InfinispanRegionFactory implements RegionFactory {
-
- private static final Logger log = LoggerFactory.getLogger(InfinispanRegionFactory.class);
-
+
+ private static final Log log = LogFactory.getLog(InfinispanRegionFactory.class);
+
private static final String PREFIX = "hibernate.cache.infinispan.";
-
+
private static final String CONFIG_SUFFIX = ".cfg";
-
+
private static final String STRATEGY_SUFFIX = ".eviction.strategy";
private static final String WAKE_UP_INTERVAL_SUFFIX = ".eviction.wake_up_interval";
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/JndiInfinispanRegionFactory.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/JndiInfinispanRegionFactory.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/JndiInfinispanRegionFactory.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -32,8 +32,8 @@
import org.hibernate.util.NamingHelper;
import org.hibernate.util.PropertiesHelper;
import org.infinispan.manager.CacheManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* A {@link RegionFactory} for <a href="http://www.jboss.org/infinispan">Infinispan</a>-backed cache
@@ -44,7 +44,7 @@
*/
public class JndiInfinispanRegionFactory extends InfinispanRegionFactory {
- private static final Logger log = LoggerFactory.getLogger(JndiInfinispanRegionFactory.class);
+ private static final Log log = LogFactory.getLog(JndiInfinispanRegionFactory.class);
/**
* Specifies the JNDI name under which the {@link CacheManager} to use is bound.
Added: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java (rev 0)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/PutFromLoadValidator.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,478 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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 Middleware LLC.
+ *
+ * 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.cache.infinispan.access;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.hibernate.cache.CacheException;
+
+/**
+ * Encapsulates logic to allow a {@link TransactionalAccessDelegate} to determine
+ * whether a {@link TransactionalAccessDelegate#putFromLoad(Object, Object, long, Object, boolean)
+ * call should be allowed to update the cache. A <code>putFromLoad</code> has
+ * the potential to store stale data, since the data may have been removed from the
+ * database and the cache between the time when the data was read from the database
+ * and the actual call to <code>putFromLoad</code>.
+ *
+ * @author Brian Stansberry
+ *
+ * @version $Revision: $
+ */
+public class PutFromLoadValidator {
+ /**
+ * Period in ms after a removal during which a call to {@link #isPutValid(Object)} that hasn't
+ * been {@link #registerPendingPut(Object) pre-registered} (aka a "naked put") will return false.
+ */
+ public static final long NAKED_PUT_INVALIDATION_PERIOD = 10 * 1000;
+
+ /** Period after which a pending put is placed in the over-age queue */
+ private static final long PENDING_PUT_OVERAGE_PERIOD = 5 * 1000;
+
+ /** Period before which we stop trying to clean out pending puts */
+ private static final long PENDING_PUT_RECENT_PERIOD = 2 * 1000;
+
+ /**
+ * Period after which a pending put is never expected to come in and should be cleaned
+ */
+ private static final long MAX_PENDING_PUT_DELAY = 2 * 60 * 1000;
+
+ /**
+ * Used to determine whether the owner of a pending put is a thread or a transaction
+ */
+ private final TransactionManager transactionManager;
+
+ private final long nakedPutInvalidationPeriod;
+ private final long pendingPutOveragePeriod;
+ private final long pendingPutRecentPeriod;
+ private final long maxPendingPutDelay;
+
+ /**
+ * Registry of expected, future, isPutValid calls. If a key+owner is registered in this map, it
+ * is not a "naked put" and is allowed to proceed.
+ */
+ private final ConcurrentMap<Object, PendingPutMap> pendingPuts = new ConcurrentHashMap<Object, PendingPutMap>();
+ /**
+ * List of pending puts. Used to ensure we don't leak memory via the pendingPuts map
+ */
+ private final List<WeakReference<PendingPut>> pendingQueue = new LinkedList<WeakReference<PendingPut>>();
+ /**
+ * Separate list of pending puts that haven't been resolved within PENDING_PUT_OVERAGE_PERIOD.
+ * Used to ensure we don't leak memory via the pendingPuts map. Tracked separately from more
+ * recent pending puts for efficiency reasons.
+ */
+ private final List<WeakReference<PendingPut>> overagePendingQueue = new LinkedList<WeakReference<PendingPut>>();
+ /** Lock controlling access to pending put queues */
+ private final Lock pendingLock = new ReentrantLock();
+ private final ConcurrentMap<Object, Long> recentRemovals = new ConcurrentHashMap<Object, Long>();
+ /**
+ * List of recent removals. Used to ensure we don't leak memory via the recentRemovals map
+ */
+ private final List<RecentRemoval> removalsQueue = new LinkedList<RecentRemoval>();
+ /**
+ * The time when the first element in removalsQueue will expire. No reason to do housekeeping on
+ * the queue before this time.
+ */
+ private volatile long earliestRemovalTimestamp;
+ /** Lock controlling access to removalsQueue */
+ private final Lock removalsLock = new ReentrantLock();
+
+ /**
+ * The time of the last call to regionRemoved(), plus NAKED_PUT_INVALIDATION_PERIOD. All naked
+ * puts will be rejected until the current time is greater than this value.
+ */
+ private volatile long invalidationTimestamp;
+
+ /**
+ * Creates a new PutFromLoadValidator.
+ *
+ * @param transactionManager
+ * transaction manager to use to associated changes with a transaction; may be
+ * <code>null</code>
+ */
+ public PutFromLoadValidator(TransactionManager transactionManager) {
+ this(transactionManager, NAKED_PUT_INVALIDATION_PERIOD, PENDING_PUT_OVERAGE_PERIOD,
+ PENDING_PUT_RECENT_PERIOD, MAX_PENDING_PUT_DELAY);
+ }
+
+ /**
+ * Constructor variant for use by unit tests; allows control of various timeouts by the test.
+ */
+ protected PutFromLoadValidator(TransactionManager transactionManager,
+ long nakedPutInvalidationPeriod, long pendingPutOveragePeriod,
+ long pendingPutRecentPeriod, long maxPendingPutDelay) {
+ this.transactionManager = transactionManager;
+ this.nakedPutInvalidationPeriod = nakedPutInvalidationPeriod;
+ this.pendingPutOveragePeriod = pendingPutOveragePeriod;
+ this.pendingPutRecentPeriod = pendingPutRecentPeriod;
+ this.maxPendingPutDelay = maxPendingPutDelay;
+ }
+
+ // ----------------------------------------------------------------- Public
+
+ public boolean isPutValid(Object key) {
+ boolean valid = false;
+ long now = System.currentTimeMillis();
+
+ PendingPutMap pending = pendingPuts.get(key);
+ if (pending != null) {
+ synchronized (pending) {
+ PendingPut toCancel = pending.remove(getOwnerForPut());
+ valid = toCancel != null;
+ if (valid) {
+ toCancel.completed = true;
+ if (pending.size() == 0) {
+ pendingPuts.remove(key);
+ }
+ }
+ }
+ }
+
+ if (!valid) {
+ if (now > invalidationTimestamp) {
+ Long removedTime = recentRemovals.get(key);
+ if (removedTime == null || now > removedTime.longValue()) {
+ valid = true;
+ }
+ }
+ }
+
+ cleanOutdatedPendingPuts(now, true);
+
+ return valid;
+ }
+
+ public void keyRemoved(Object key) {
+ // Invalidate any pending puts
+ pendingPuts.remove(key);
+
+ // Record when this occurred to invalidate later naked puts
+ RecentRemoval removal = new RecentRemoval(key, this.nakedPutInvalidationPeriod);
+ recentRemovals.put(key, removal.timestamp);
+
+ // Don't let recentRemovals map become a memory leak
+ RecentRemoval toClean = null;
+ boolean attemptClean = removal.timestamp.longValue() > earliestRemovalTimestamp;
+ removalsLock.lock();
+ try {
+ removalsQueue.add(removal);
+
+ if (attemptClean) {
+ if (removalsQueue.size() > 1) { // we have at least one as we
+ // just added it
+ toClean = removalsQueue.remove(0);
+ }
+ earliestRemovalTimestamp = removalsQueue.get(0).timestamp.longValue();
+ }
+ } finally {
+ removalsLock.unlock();
+ }
+
+ if (toClean != null) {
+ Long cleaned = recentRemovals.get(toClean.key);
+ if (cleaned != null && cleaned.equals(toClean.timestamp)) {
+ cleaned = recentRemovals.remove(toClean.key);
+ if (cleaned != null && cleaned.equals(toClean.timestamp) == false) {
+ // Oops; removed the wrong timestamp; restore it
+ recentRemovals.putIfAbsent(toClean.key, cleaned);
+ }
+ }
+ }
+ }
+
+ public void cleared() {
+ invalidationTimestamp = System.currentTimeMillis() + this.nakedPutInvalidationPeriod;
+ pendingLock.lock();
+ try {
+ removalsLock.lock();
+ try {
+ pendingPuts.clear();
+ pendingQueue.clear();
+ overagePendingQueue.clear();
+ recentRemovals.clear();
+ removalsQueue.clear();
+ earliestRemovalTimestamp = invalidationTimestamp;
+
+ } finally {
+ removalsLock.unlock();
+ }
+ } finally {
+ pendingLock.unlock();
+ }
+ }
+
+ /**
+ * Notifies this validator that it is expected that a database read followed by a subsequent
+ * {@link #isPutValid(Object)} call will occur. The intent is this method would be called
+ * following a cache miss wherein it is expected that a database read plus cache put will occur.
+ * Calling this method allows the validator to treat the subsequent <code>isPutValid</code> as if
+ * the database read occurred when this method was invoked. This allows the validator to compare
+ * the timestamp of this call against the timestamp of subsequent removal notifications. A put
+ * that occurs without this call preceding it is "naked"; i.e the validator must assume the put
+ * is not valid if any relevant removal has occurred within
+ * {@link #NAKED_PUT_INVALIDATION_PERIOD} milliseconds.
+ *
+ * @param key
+ * key that will be used for subsequent put
+ */
+ public void registerPendingPut(Object key) {
+ PendingPut pendingPut = new PendingPut(key, getOwnerForPut());
+ PendingPutMap pendingForKey = new PendingPutMap();
+ synchronized (pendingForKey) {
+ for (;;) {
+ PendingPutMap existing = pendingPuts.putIfAbsent(key, pendingForKey);
+ if (existing != null && existing != pendingForKey) {
+ synchronized (existing) {
+ existing.put(pendingPut);
+ PendingPutMap doublecheck = pendingPuts.putIfAbsent(key, existing);
+ if (doublecheck == null || doublecheck == existing) {
+ break;
+ }
+ // else we hit a race and need to loop to try again
+ }
+ } else {
+ pendingForKey.put(pendingPut);
+ break;
+ }
+ }
+ }
+
+ // Guard against memory leaks
+ preventOutdatedPendingPuts(pendingPut);
+ }
+
+ // -------------------------------------------------------------- Protected
+
+ /** Only for use by unit tests; may be removed at any time */
+ protected int getPendingPutQueueLength() {
+ pendingLock.lock();
+ try {
+ return pendingQueue.size();
+ } finally {
+ pendingLock.unlock();
+ }
+ }
+
+ /** Only for use by unit tests; may be removed at any time */
+ protected int getOveragePendingPutQueueLength() {
+ pendingLock.lock();
+ try {
+ return overagePendingQueue.size();
+ } finally {
+ pendingLock.unlock();
+ }
+ }
+
+ /** Only for use by unit tests; may be removed at any time */
+ protected int getRemovalQueueLength() {
+ removalsLock.lock();
+ try {
+ return removalsQueue.size();
+ } finally {
+ removalsLock.unlock();
+ }
+ }
+
+ // ---------------------------------------------------------------- Private
+
+ private Object getOwnerForPut() {
+ Transaction tx = null;
+ try {
+ if (transactionManager != null) {
+ tx = transactionManager.getTransaction();
+ }
+ } catch (SystemException se) {
+ throw new CacheException("Could not obtain transaction", se);
+ }
+ return tx == null ? Thread.currentThread() : tx;
+
+ }
+
+ private void preventOutdatedPendingPuts(PendingPut pendingPut) {
+ pendingLock.lock();
+ try {
+ pendingQueue.add(new WeakReference<PendingPut>(pendingPut));
+ cleanOutdatedPendingPuts(pendingPut.timestamp, false);
+ } finally {
+ pendingLock.unlock();
+ }
+ }
+
+ private void cleanOutdatedPendingPuts(long now, boolean lock) {
+
+ PendingPut toClean = null;
+ if (lock) {
+ pendingLock.lock();
+ }
+ try {
+
+ // Clean items out of the basic queue
+
+ long overaged = now - this.pendingPutOveragePeriod;
+ long recent = now - this.pendingPutRecentPeriod;
+
+ int pos = 0;
+ while (pendingQueue.size() > pos) {
+ WeakReference<PendingPut> ref = pendingQueue.get(pos);
+ PendingPut item = ref.get();
+ if (item == null || item.completed) {
+ pendingQueue.remove(pos);
+ } else if (item.timestamp < overaged) {
+ // Potential leak; move to the overaged queued
+ pendingQueue.remove(pos);
+ overagePendingQueue.add(ref);
+ } else if (item.timestamp >= recent) {
+ // Don't waste time on very recent items
+ break;
+ } else if (pos > 2) {
+ // Don't spend too much time getting nowhere
+ break;
+ } else {
+ // Move on to the next item
+ pos++;
+ }
+ }
+
+ // Process the overage queue until we find an item to clean
+ // or an incomplete item that hasn't aged out
+ long mustCleanTime = now - this.maxPendingPutDelay;
+
+ while (overagePendingQueue.size() > 0) {
+ WeakReference<PendingPut> ref = overagePendingQueue.get(0);
+ PendingPut item = ref.get();
+ if (item == null || item.completed) {
+ overagePendingQueue.remove(0);
+ } else {
+ if (item.timestamp < mustCleanTime) {
+ overagePendingQueue.remove(0);
+ toClean = item;
+ }
+ break;
+ }
+ }
+ } finally {
+ if (lock) {
+ pendingLock.unlock();
+ }
+ }
+
+ // We've found a pendingPut that never happened; clean it up
+ if (toClean != null) {
+ PendingPutMap map = pendingPuts.get(toClean.key);
+ if (map != null) {
+ synchronized (map) {
+ PendingPut cleaned = map.remove(toClean.owner);
+ if (toClean.equals(cleaned) == false) {
+ // Oops. Restore it.
+ map.put(cleaned);
+ } else if (map.size() == 0) {
+ pendingPuts.remove(toClean.key);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Lazy-initialization map for PendingPut. Optimized for the expected usual case where only a
+ * single put is pending for a given key.
+ *
+ * This class is NOT THREAD SAFE. All operations on it must be performed with the object monitor
+ * held.
+ */
+ private static class PendingPutMap {
+ private PendingPut singlePendingPut;
+ private Map<Object, PendingPut> fullMap;
+
+ public void put(PendingPut pendingPut) {
+ if (singlePendingPut == null) {
+ if (fullMap == null) {
+ // initial put
+ singlePendingPut = pendingPut;
+ } else {
+ fullMap.put(pendingPut.owner, pendingPut);
+ }
+ } else {
+ // 2nd put; need a map
+ fullMap = new HashMap<Object, PendingPut>(4);
+ fullMap.put(singlePendingPut.owner, singlePendingPut);
+ singlePendingPut = null;
+ fullMap.put(pendingPut.owner, pendingPut);
+ }
+ }
+
+ public PendingPut remove(Object ownerForPut) {
+ PendingPut removed = null;
+ if (fullMap == null) {
+ if (singlePendingPut != null && singlePendingPut.owner.equals(ownerForPut)) {
+ removed = singlePendingPut;
+ singlePendingPut = null;
+ }
+ } else {
+ removed = fullMap.remove(ownerForPut);
+ }
+ return removed;
+ }
+
+ public int size() {
+ return fullMap == null ? (singlePendingPut == null ? 0 : 1) : fullMap.size();
+ }
+ }
+
+ private static class PendingPut {
+ private final Object key;
+ private final Object owner;
+ private final long timestamp = System.currentTimeMillis();
+ private volatile boolean completed;
+
+ private PendingPut(Object key, Object owner) {
+ this.key = key;
+ this.owner = owner;
+ }
+
+ }
+
+ private static class RecentRemoval {
+ private final Object key;
+ private final Long timestamp;
+
+ private RecentRemoval(Object key, long nakedPutInvalidationPeriod) {
+ this.key = key;
+ timestamp = Long.valueOf(System.currentTimeMillis() + nakedPutInvalidationPeriod);
+ }
+ }
+
+}
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/access/TransactionalAccessDelegate.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -32,6 +32,8 @@
import org.hibernate.cache.infinispan.impl.BaseRegion;
import org.hibernate.cache.infinispan.util.CacheAdapter;
import org.hibernate.cache.infinispan.util.CacheHelper;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* Defines the strategy for transactional access to entity or collection data in a Infinispan instance.
@@ -44,31 +46,50 @@
* @since 3.5
*/
public class TransactionalAccessDelegate {
-
+ private static final Log log = LogFactory.getLog(TransactionalAccessDelegate.class);
protected final CacheAdapter cacheAdapter;
protected final BaseRegion region;
+ protected final PutFromLoadValidator putValidator;
- public TransactionalAccessDelegate(BaseRegion region) {
+ public TransactionalAccessDelegate(BaseRegion region, PutFromLoadValidator validator) {
this.region = region;
this.cacheAdapter = region.getCacheAdapter();
+ this.putValidator = validator;
}
public Object get(Object key, long txTimestamp) throws CacheException {
if (!region.checkValid())
return null;
- return cacheAdapter.get(key);
+ Object val = cacheAdapter.get(key);
+ if (val == null)
+ putValidator.registerPendingPut(key);
+ return val;
}
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
- if (!region.checkValid())
+ if (!region.checkValid()) {
return false;
+ }
+ if (!putValidator.isPutValid(key)) {
+ return false;
+ }
cacheAdapter.putForExternalRead(key, value);
return true;
}
public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version, boolean minimalPutOverride)
throws CacheException {
- return putFromLoad(key, value, txTimestamp, version);
+ boolean trace = log.isTraceEnabled();
+ if (!region.checkValid()) {
+ if (trace) log.trace("Region not valid");
+ return false;
+ }
+ if (!putValidator.isPutValid(key)) {
+ if (trace) log.trace("Put {0} not valid", key);
+ return false;
+ }
+ cacheAdapter.putForExternalRead(key, value);
+ return true;
}
public SoftLock lockItem(Object key, Object version) throws CacheException {
@@ -113,18 +134,22 @@
// We update whether or not the region is valid. Other nodes
// may have already restored the region so they need to
// be informed of the change.
+ putValidator.keyRemoved(key);
cacheAdapter.remove(key);
}
public void removeAll() throws CacheException {
+ putValidator.cleared();
cacheAdapter.clear();
}
public void evict(Object key) throws CacheException {
+ putValidator.keyRemoved(key);
cacheAdapter.remove(key);
}
public void evictAll() throws CacheException {
+ putValidator.cleared();
Transaction tx = region.suspend();
try {
CacheHelper.sendEvictAllNotification(cacheAdapter, region.getAddress());
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/CollectionRegionImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -7,6 +7,7 @@
import org.hibernate.cache.CollectionRegion;
import org.hibernate.cache.access.AccessType;
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.infinispan.access.PutFromLoadValidator;
import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion;
import org.hibernate.cache.infinispan.util.CacheAdapter;
import org.infinispan.notifications.Listener;
@@ -32,4 +33,7 @@
throw new CacheException("Unsupported access type [" + accessType.getName() + "]");
}
+ public PutFromLoadValidator getPutFromLoadValidator() {
+ return new PutFromLoadValidator(transactionManager);
+ }
}
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/ReadOnlyAccess.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/ReadOnlyAccess.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/ReadOnlyAccess.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -2,8 +2,8 @@
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.SoftLock;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* This defines the strategy for transactional access to collection data in a
@@ -17,7 +17,7 @@
* @since 3.5
*/
class ReadOnlyAccess extends TransactionalAccess {
- private static final Logger log = LoggerFactory.getLogger(ReadOnlyAccess.class);
+ private static final Log log = LogFactory.getLog(ReadOnlyAccess.class);
ReadOnlyAccess(CollectionRegionImpl region) {
super(region);
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/collection/TransactionalAccess.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -21,7 +21,7 @@
TransactionalAccess(CollectionRegionImpl region) {
this.region = region;
- this.delegate = new TransactionalAccessDelegate(region);
+ this.delegate = new TransactionalAccessDelegate(region, region.getPutFromLoadValidator());
}
public void evict(Object key) throws CacheException {
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/EntityRegionImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -7,6 +7,7 @@
import org.hibernate.cache.EntityRegion;
import org.hibernate.cache.access.AccessType;
import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.infinispan.access.PutFromLoadValidator;
import org.hibernate.cache.infinispan.impl.BaseTransactionalDataRegion;
import org.hibernate.cache.infinispan.util.CacheAdapter;
import org.infinispan.notifications.Listener;
@@ -32,4 +33,7 @@
throw new CacheException("Unsupported access type [" + accessType.getName() + "]");
}
+ public PutFromLoadValidator getPutFromLoadValidator() {
+ return new PutFromLoadValidator(transactionManager);
+ }
}
\ No newline at end of file
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/ReadOnlyAccess.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -2,8 +2,8 @@
import org.hibernate.cache.CacheException;
import org.hibernate.cache.access.SoftLock;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* A specialization of {@link TransactionalAccess} that ensures we never update data. Infinispan
@@ -14,7 +14,7 @@
* @since 3.5
*/
class ReadOnlyAccess extends TransactionalAccess {
- private static final Logger log = LoggerFactory.getLogger(ReadOnlyAccess.class);
+ private static final Log log = LogFactory.getLog(ReadOnlyAccess.class);
ReadOnlyAccess(EntityRegionImpl region) {
super(region);
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/entity/TransactionalAccess.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -21,7 +21,7 @@
TransactionalAccess(EntityRegionImpl region) {
this.region = region;
- this.delegate = new TransactionalAccessDelegate(region);
+ this.delegate = new TransactionalAccessDelegate(region, region.getPutFromLoadValidator());
}
public void evict(Object key) throws CacheException {
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseRegion.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseRegion.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/impl/BaseRegion.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -1,6 +1,7 @@
package org.hibernate.cache.infinispan.impl;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -130,11 +131,13 @@
public Map toMap() {
if (checkValid()) {
- Map map = cacheAdapter.toMap();
- Set keys = map.keySet();
- for (Object key : keys) {
- if (CacheHelper.isEvictAllNotification(key)) {
- map.remove(key);
+ // If copying causes issues, provide a lazily loaded Map
+ Map map = new HashMap();
+ Set<Map.Entry> entries = cacheAdapter.toMap().entrySet();
+ for (Map.Entry entry : entries) {
+ Object key = entry.getKey();
+ if (!CacheHelper.isEvictAllNotification(key)) {
+ map.put(key, entry.getValue());
}
}
return map;
@@ -149,7 +152,7 @@
cacheAdapter.removeListener(this);
}
}
-
+
public boolean contains(Object key) {
if (!checkValid())
return false;
@@ -209,7 +212,19 @@
resume(tx);
}
}
-
+
+ public Object getOwnerForPut() {
+ Transaction tx = null;
+ try {
+ if (transactionManager != null) {
+ tx = transactionManager.getTransaction();
+ }
+ } catch (SystemException se) {
+ throw new CacheException("Could not obtain transaction", se);
+ }
+ return tx == null ? Thread.currentThread() : tx;
+ }
+
/**
* Tell the TransactionManager to suspend any ongoing transaction.
*
Modified: core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheHelper.java
===================================================================
--- core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheHelper.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheHelper.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -29,8 +29,8 @@
import java.io.ObjectOutput;
import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* Helper for dealing with Infinisan cache instances.
@@ -40,7 +40,7 @@
*/
public class CacheHelper {
- private static final Logger log = LoggerFactory.getLogger(CacheHelper.class);
+ private static final Log log = LogFactory.getLog(CacheHelper.class);
/**
* Disallow external instantiation of CacheHelper.
Added: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java (rev 0)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/access/PutFromLoadValidatorUnitTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,414 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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 Middleware LLC.
+ *
+ * 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.cache.infinispan.access;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.hibernate.cache.infinispan.access.PutFromLoadValidator;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests of {@link PutFromLoadValidator}.
+ *
+ * @author Brian Stansberry
+ * @author Galder Zamarreño
+ *
+ * @version $Revision: $
+ */
+public class PutFromLoadValidatorUnitTestCase extends TestCase {
+ private Object KEY1 = "KEY1";
+
+ private TransactionManager tm;
+
+ public PutFromLoadValidatorUnitTestCase(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ tm = DualNodeJtaTransactionManagerImpl.getInstance("test");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ try {
+ super.tearDown();
+ } finally {
+ tm = null;
+ try {
+ DualNodeJtaTransactionManagerImpl.cleanupTransactions();
+ } finally {
+ DualNodeJtaTransactionManagerImpl.cleanupTransactionManagers();
+ }
+ }
+ }
+
+ public void testNakedPut() throws Exception {
+ nakedPutTest(false);
+ }
+
+ public void testNakedPutTransactional() throws Exception {
+ nakedPutTest(true);
+ }
+
+ private void nakedPutTest(boolean transactional) throws Exception {
+ PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+ if (transactional) {
+ tm.begin();
+ }
+ assertTrue(testee.isPutValid(KEY1));
+ }
+
+ public void testRegisteredPut() throws Exception {
+ registeredPutTest(false);
+ }
+
+ public void testRegisteredPutTransactional() throws Exception {
+ registeredPutTest(true);
+ }
+
+ private void registeredPutTest(boolean transactional) throws Exception {
+ PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+ if (transactional) {
+ tm.begin();
+ }
+ testee.registerPendingPut(KEY1);
+ assertTrue(testee.isPutValid(KEY1));
+ }
+
+ public void testNakedPutAfterKeyRemoval() throws Exception {
+ nakedPutAfterRemovalTest(false, false);
+ }
+
+ public void testNakedPutAfterKeyRemovalTransactional() throws Exception {
+ nakedPutAfterRemovalTest(true, false);
+ }
+
+ public void testNakedPutAfterRegionRemoval() throws Exception {
+ nakedPutAfterRemovalTest(false, true);
+ }
+
+ public void testNakedPutAfterRegionRemovalTransactional() throws Exception {
+ nakedPutAfterRemovalTest(true, true);
+ }
+
+ private void nakedPutAfterRemovalTest(boolean transactional, boolean removeRegion)
+ throws Exception {
+ PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+ if (removeRegion) {
+ testee.cleared();
+ } else {
+ testee.keyRemoved(KEY1);
+ }
+ if (transactional) {
+ tm.begin();
+ }
+ assertFalse(testee.isPutValid(KEY1));
+
+ }
+
+ public void testRegisteredPutAfterKeyRemoval() throws Exception {
+ registeredPutAfterRemovalTest(false, false);
+ }
+
+ public void testRegisteredPutAfterKeyRemovalTransactional() throws Exception {
+ registeredPutAfterRemovalTest(true, false);
+ }
+
+ public void testRegisteredPutAfterRegionRemoval() throws Exception {
+ registeredPutAfterRemovalTest(false, true);
+ }
+
+ public void testRegisteredPutAfterRegionRemovalTransactional() throws Exception {
+ registeredPutAfterRemovalTest(true, true);
+ }
+
+ private void registeredPutAfterRemovalTest(boolean transactional, boolean removeRegion)
+ throws Exception {
+ PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+ if (removeRegion) {
+ testee.cleared();
+ } else {
+ testee.keyRemoved(KEY1);
+ }
+ if (transactional) {
+ tm.begin();
+ }
+ testee.registerPendingPut(KEY1);
+ assertTrue(testee.isPutValid(KEY1));
+ }
+
+ public void testRegisteredPutWithInterveningKeyRemoval() throws Exception {
+ registeredPutWithInterveningRemovalTest(false, false);
+ }
+
+ public void testRegisteredPutWithInterveningKeyRemovalTransactional() throws Exception {
+ registeredPutWithInterveningRemovalTest(true, false);
+ }
+
+ public void testRegisteredPutWithInterveningRegionRemoval() throws Exception {
+ registeredPutWithInterveningRemovalTest(false, true);
+ }
+
+ public void testRegisteredPutWithInterveningRegionRemovalTransactional() throws Exception {
+ registeredPutWithInterveningRemovalTest(true, true);
+ }
+
+ private void registeredPutWithInterveningRemovalTest(boolean transactional, boolean removeRegion)
+ throws Exception {
+ PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+ if (transactional) {
+ tm.begin();
+ }
+ testee.registerPendingPut(KEY1);
+ if (removeRegion) {
+ testee.cleared();
+ } else {
+ testee.keyRemoved(KEY1);
+ }
+ assertFalse(testee.isPutValid(KEY1));
+ }
+
+ public void testDelayedNakedPutAfterKeyRemoval() throws Exception {
+ delayedNakedPutAfterRemovalTest(false, false);
+ }
+
+ public void testDelayedNakedPutAfterKeyRemovalTransactional() throws Exception {
+ delayedNakedPutAfterRemovalTest(true, false);
+ }
+
+ public void testDelayedNakedPutAfterRegionRemoval() throws Exception {
+ delayedNakedPutAfterRemovalTest(false, true);
+ }
+
+ public void testDelayedNakedPutAfterRegionRemovalTransactional() throws Exception {
+ delayedNakedPutAfterRemovalTest(true, true);
+ }
+
+ private void delayedNakedPutAfterRemovalTest(boolean transactional, boolean removeRegion)
+ throws Exception {
+ PutFromLoadValidator testee = new TestValidator(transactional ? tm : null, 100, 1000, 500,
+ 10000);
+ if (removeRegion) {
+ testee.cleared();
+ } else {
+ testee.keyRemoved(KEY1);
+ }
+ if (transactional) {
+ tm.begin();
+ }
+ Thread.sleep(110);
+ assertTrue(testee.isPutValid(KEY1));
+
+ }
+
+ public void testMultipleRegistrations() throws Exception {
+ multipleRegistrationtest(false);
+ }
+
+ public void testMultipleRegistrationsTransactional() throws Exception {
+ multipleRegistrationtest(true);
+ }
+
+ private void multipleRegistrationtest(final boolean transactional) throws Exception {
+ final PutFromLoadValidator testee = new PutFromLoadValidator(transactional ? tm : null);
+
+ final CountDownLatch registeredLatch = new CountDownLatch(3);
+ final CountDownLatch finishedLatch = new CountDownLatch(3);
+ final AtomicInteger success = new AtomicInteger();
+
+ Runnable r = new Runnable() {
+ public void run() {
+ try {
+ if (transactional) {
+ tm.begin();
+ }
+ testee.registerPendingPut(KEY1);
+ registeredLatch.countDown();
+ registeredLatch.await(5, TimeUnit.SECONDS);
+ if (testee.isPutValid(KEY1)) {
+ success.incrementAndGet();
+ }
+ finishedLatch.countDown();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ ExecutorService executor = Executors.newFixedThreadPool(3);
+
+ // Start with a removal so the "isPutValid" calls will fail if
+ // any of the concurrent activity isn't handled properly
+
+ testee.cleared();
+
+ // Do the registration + isPutValid calls
+ executor.execute(r);
+ executor.execute(r);
+ executor.execute(r);
+
+ finishedLatch.await(5, TimeUnit.SECONDS);
+
+ assertEquals("All threads succeeded", 3, success.get());
+ }
+
+ /**
+ * White box test for ensuring key removals get cleaned up.
+ *
+ * @throws Exception
+ */
+ public void testRemovalCleanup() throws Exception {
+ TestValidator testee = new TestValidator(null, 200, 1000, 500, 10000);
+ testee.keyRemoved("KEY1");
+ testee.keyRemoved("KEY2");
+ Thread.sleep(210);
+ assertEquals(2, testee.getRemovalQueueLength());
+ testee.keyRemoved("KEY1");
+ assertEquals(2, testee.getRemovalQueueLength());
+ testee.keyRemoved("KEY2");
+ assertEquals(2, testee.getRemovalQueueLength());
+ }
+
+ /**
+ * Very much a white box test of the logic for ensuring pending put registrations get cleaned up.
+ *
+ * @throws Exception
+ */
+ public void testPendingPutCleanup() throws Exception {
+ TestValidator testee = new TestValidator(tm, 5000, 600, 300, 900);
+
+ // Start with a regionRemoval so we can confirm at the end that all
+ // registrations have been cleaned out
+ testee.cleared();
+
+ testee.registerPendingPut("1");
+ testee.registerPendingPut("2");
+ testee.registerPendingPut("3");
+ testee.registerPendingPut("4");
+ testee.registerPendingPut("5");
+ testee.registerPendingPut("6");
+ testee.isPutValid("6");
+ testee.isPutValid("2");
+ // ppq = [1,2(c),3,4,5,6(c)]
+ assertEquals(6, testee.getPendingPutQueueLength());
+ assertEquals(0, testee.getOveragePendingPutQueueLength());
+
+ // Sleep past "pendingPutRecentPeriod"
+ Thread.sleep(310);
+ testee.registerPendingPut("7");
+ // White box -- should have cleaned out 2 (completed) but
+ // not gotten to 6 (also removed)
+ // ppq = [1,3,4,5,6(c),7]
+ assertEquals(0, testee.getOveragePendingPutQueueLength());
+ assertEquals(6, testee.getPendingPutQueueLength());
+
+ // Sleep past "pendingPutOveragePeriod"
+ Thread.sleep(310);
+ testee.registerPendingPut("8");
+ // White box -- should have cleaned out 6 (completed) and
+ // moved 1, 3, 4 and 5 to overage queue
+ // oppq = [1,3,4,5] ppq = [7,8]
+ assertEquals(4, testee.getOveragePendingPutQueueLength());
+ assertEquals(2, testee.getPendingPutQueueLength());
+
+ // Sleep past "maxPendingPutDelay"
+ Thread.sleep(310);
+ testee.isPutValid("3");
+ // White box -- should have cleaned out 1 (overage) and
+ // moved 7 to overage queue
+ // oppq = [3(c),4,5,7] ppq=[8]
+ assertEquals(4, testee.getOveragePendingPutQueueLength());
+ assertEquals(1, testee.getPendingPutQueueLength());
+
+ // Sleep past "maxPendingPutDelay"
+ Thread.sleep(310);
+ tm.begin();
+ testee.registerPendingPut("7");
+ Transaction tx = tm.suspend();
+
+ // White box -- should have cleaned out 3 (completed)
+ // and 4 (overage) and moved 8 to overage queue
+ // We now have 5,7,8 in overage and 7tx in pending
+ // oppq = [5,7,8] ppq=[7tx]
+ assertEquals(3, testee.getOveragePendingPutQueueLength());
+ assertEquals(1, testee.getPendingPutQueueLength());
+
+ // Validate that only expected items can do puts, thus indirectly
+ // proving the others have been cleaned out of pendingPuts map
+ assertFalse(testee.isPutValid("1"));
+ // 5 was overage, so should have been cleaned
+ assertEquals(2, testee.getOveragePendingPutQueueLength());
+ assertFalse(testee.isPutValid("2"));
+ // 7 was overage, so should have been cleaned
+ assertEquals(1, testee.getOveragePendingPutQueueLength());
+ assertFalse(testee.isPutValid("3"));
+ assertFalse(testee.isPutValid("4"));
+ assertFalse(testee.isPutValid("5"));
+ assertFalse(testee.isPutValid("6"));
+ assertFalse(testee.isPutValid("7"));
+ assertTrue(testee.isPutValid("8"));
+ tm.resume(tx);
+ assertTrue(testee.isPutValid("7"));
+ }
+
+ private static class TestValidator extends PutFromLoadValidator {
+
+ protected TestValidator(TransactionManager transactionManager,
+ long nakedPutInvalidationPeriod, long pendingPutOveragePeriod,
+ long pendingPutRecentPeriod, long maxPendingPutDelay) {
+ super(transactionManager, nakedPutInvalidationPeriod, pendingPutOveragePeriod,
+ pendingPutRecentPeriod, maxPendingPutDelay);
+ }
+
+ @Override
+ public int getOveragePendingPutQueueLength() {
+ // TODO Auto-generated method stub
+ return super.getOveragePendingPutQueueLength();
+ }
+
+ @Override
+ public int getPendingPutQueueLength() {
+ // TODO Auto-generated method stub
+ return super.getPendingPutQueueLength();
+ }
+
+ @Override
+ public int getRemovalQueueLength() {
+ // TODO Auto-generated method stub
+ return super.getRemovalQueueLength();
+ }
+
+ }
+}
Added: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java (rev 0)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/collection/CollectionRegionImplTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2007, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cache.infinispan.collection;
+
+import java.util.Properties;
+
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.Region;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.access.AccessType;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.infinispan.InfinispanRegionFactory;
+import org.hibernate.cache.infinispan.util.CacheAdapter;
+import org.hibernate.cache.infinispan.util.CacheAdapterImpl;
+import org.hibernate.test.cache.infinispan.AbstractEntityCollectionRegionTestCase;
+
+/**
+ * Tests of CollectionRegionImpl.
+ *
+ * @author Galder Zamarreño
+ */
+public class CollectionRegionImplTestCase extends AbstractEntityCollectionRegionTestCase {
+
+ public CollectionRegionImplTestCase(String name) {
+ super(name);
+ }
+
+ @Override
+ protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) {
+ CollectionRegion region = regionFactory.buildCollectionRegion("test", properties, null);
+ assertNull("Got TRANSACTIONAL", region.buildAccessStrategy(AccessType.TRANSACTIONAL)
+ .lockRegion());
+ try {
+ region.buildAccessStrategy(AccessType.READ_ONLY).lockRegion();
+ fail("Did not get READ_ONLY");
+ } catch (UnsupportedOperationException good) {
+ }
+
+ try {
+ region.buildAccessStrategy(AccessType.NONSTRICT_READ_WRITE);
+ fail("Incorrectly got NONSTRICT_READ_WRITE");
+ } catch (CacheException good) {
+ }
+
+ try {
+ region.buildAccessStrategy(AccessType.READ_WRITE);
+ fail("Incorrectly got READ_WRITE");
+ } catch (CacheException good) {
+ }
+ }
+
+ @Override
+ protected Region createRegion(InfinispanRegionFactory regionFactory, String regionName, Properties properties, CacheDataDescription cdd) {
+ return regionFactory.buildCollectionRegion(regionName, properties, cdd);
+ }
+
+ @Override
+ protected CacheAdapter getInfinispanCache(InfinispanRegionFactory regionFactory) {
+ return CacheAdapterImpl.newInstance(regionFactory.getCacheManager().getCache(InfinispanRegionFactory.DEF_ENTITY_RESOURCE));
+ }
+
+ @Override
+ protected void putInRegion(Region region, Object key, Object value) {
+ CollectionRegionAccessStrategy strategy = ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL);
+ strategy.putFromLoad(key, value, System.currentTimeMillis(), new Integer(1));
+ }
+
+ @Override
+ protected void removeFromRegion(Region region, Object key) {
+ ((CollectionRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key);
+ }
+
+}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractEntityRegionAccessStrategyTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -434,9 +434,7 @@
final String KEY = KEY_BASE + testCount++;
// Set up initial state
- localAccessStrategy.get(KEY, System.currentTimeMillis());
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
- remoteAccessStrategy.get(KEY, System.currentTimeMillis());
remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
// Let the async put propagate
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/AbstractTransactionalAccessTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -52,7 +52,6 @@
final String KEY = KEY_BASE + testCount++;
- localAccessStrategy.get(KEY, System.currentTimeMillis());
localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
final CountDownLatch pferLatch = new CountDownLatch(1);
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/entity/EntityRegionImplTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -43,60 +43,53 @@
* @since 3.5
*/
public class EntityRegionImplTestCase extends AbstractEntityCollectionRegionTestCase {
-
- public EntityRegionImplTestCase(String name) {
- super(name);
- }
-
- @Override
- protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) {
-
- EntityRegion region = regionFactory.buildEntityRegion("test", properties, null);
-
- assertNull("Got TRANSACTIONAL", region.buildAccessStrategy(AccessType.TRANSACTIONAL).lockRegion());
-
- try
- {
- region.buildAccessStrategy(AccessType.READ_ONLY).lockRegion();
- fail("Did not get READ_ONLY");
- }
- catch (UnsupportedOperationException good) {}
-
- try
- {
- region.buildAccessStrategy(AccessType.NONSTRICT_READ_WRITE);
- fail("Incorrectly got NONSTRICT_READ_WRITE");
- }
- catch (CacheException good) {}
-
- try
- {
- region.buildAccessStrategy(AccessType.READ_WRITE);
- fail("Incorrectly got READ_WRITE");
- }
- catch (CacheException good) {}
-
- }
- @Override
- protected void putInRegion(Region region, Object key, Object value) {
- ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).insert(key, value, new Integer(1));
- }
+ public EntityRegionImplTestCase(String name) {
+ super(name);
+ }
- @Override
- protected void removeFromRegion(Region region, Object key) {
- ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key);
- }
+ @Override
+ protected void supportedAccessTypeTest(RegionFactory regionFactory, Properties properties) {
+ EntityRegion region = regionFactory.buildEntityRegion("test", properties, null);
+ assertNull("Got TRANSACTIONAL", region.buildAccessStrategy(AccessType.TRANSACTIONAL)
+ .lockRegion());
+ try {
+ region.buildAccessStrategy(AccessType.READ_ONLY).lockRegion();
+ fail("Did not get READ_ONLY");
+ } catch (UnsupportedOperationException good) {
+ }
+ try {
+ region.buildAccessStrategy(AccessType.NONSTRICT_READ_WRITE);
+ fail("Incorrectly got NONSTRICT_READ_WRITE");
+ } catch (CacheException good) {
+ }
+
+ try {
+ region.buildAccessStrategy(AccessType.READ_WRITE);
+ fail("Incorrectly got READ_WRITE");
+ } catch (CacheException good) {
+ }
+ }
+
@Override
- protected Region createRegion(InfinispanRegionFactory regionFactory, String regionName,
- Properties properties, CacheDataDescription cdd) {
+ protected void putInRegion(Region region, Object key, Object value) {
+ ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).insert(key, value, new Integer(1));
+ }
+
+ @Override
+ protected void removeFromRegion(Region region, Object key) {
+ ((EntityRegion) region).buildAccessStrategy(AccessType.TRANSACTIONAL).remove(key);
+ }
+
+ @Override
+ protected Region createRegion(InfinispanRegionFactory regionFactory, String regionName, Properties properties, CacheDataDescription cdd) {
return regionFactory.buildEntityRegion(regionName, properties, cdd);
}
@Override
protected CacheAdapter getInfinispanCache(InfinispanRegionFactory regionFactory) {
- return CacheAdapterImpl.newInstance(regionFactory.getCacheManager().getCache("entity"));
+ return CacheAdapterImpl.newInstance(regionFactory.getCacheManager().getCache(InfinispanRegionFactory.DEF_ENTITY_RESOURCE));
}
}
Deleted: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -1,38 +0,0 @@
-package org.hibernate.test.cache.infinispan.functional;
-
-import java.util.Map;
-
-import org.hibernate.junit.functional.FunctionalTestCase;
-import org.hibernate.stat.SecondLevelCacheStatistics;
-import org.hibernate.stat.Statistics;
-
-/**
- * @author Galder Zamarreño
- * @since 3.5
- */
-public abstract class AbstractFunctionalTestCase extends FunctionalTestCase {
- private final String cacheConcurrencyStrategy;
-
- public AbstractFunctionalTestCase(String string, String cacheConcurrencyStrategy) {
- super(string);
- this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
- }
-
- public String[] getMappings() {
- return new String[] { "cache/infinispan/functional/Item.hbm.xml" };
- }
-
- @Override
- public String getCacheConcurrencyStrategy() {
- return cacheConcurrencyStrategy;
- }
-
- public void testEmptySecondLevelCacheEntry() throws Exception {
- getSessions().getCache().evictEntityRegion(Item.class.getName());
- Statistics stats = getSessions().getStatistics();
- stats.clear();
- SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics(Item.class.getName() + ".items");
- Map cacheEntries = statistics.getEntries();
- assertEquals(0, cacheEntries.size());
- }
-}
\ No newline at end of file
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicReadOnlyTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicReadOnlyTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicReadOnlyTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -4,10 +4,15 @@
* @author Galder Zamarreño
* @since 3.5
*/
-public class BasicReadOnlyTestCase extends AbstractFunctionalTestCase {
+public class BasicReadOnlyTestCase extends SingleNodeTestCase {
public BasicReadOnlyTestCase(String string) {
- super(string, "read-only");
+ super(string);
}
+ @Override
+ public String getCacheConcurrencyStrategy() {
+ return "read-only";
+ }
+
}
\ No newline at end of file
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/BasicTransactionalTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -6,106 +6,154 @@
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.cfg.Configuration;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* @author Galder Zamarreño
* @since 3.5
*/
-public class BasicTransactionalTestCase extends AbstractFunctionalTestCase {
+public class BasicTransactionalTestCase extends SingleNodeTestCase {
+ private static final Log log = LogFactory.getLog(BasicTransactionalTestCase.class);
public BasicTransactionalTestCase(String string) {
- super(string, "transactional");
+ super(string);
}
- public void testEntityCache() {
+ @Override
+ public void configure(Configuration cfg) {
+ super.configure(cfg);
+ }
+
+ public void testEntityCache() throws Exception {
Item item = new Item("chris", "Chris's Item");
+ beginTx();
+ try {
+ Session s = openSession();
+ s.getTransaction().begin();
+ s.persist(item);
+ s.getTransaction().commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- Session s = openSession();
- Statistics stats = s.getSessionFactory().getStatistics();
- s.getTransaction().begin();
- s.persist(item);
- s.getTransaction().commit();
- s.close();
+ beginTx();
+ try {
+ Session s = openSession();
+ Item found = (Item) s.load(Item.class, item.getId());
+ Statistics stats = s.getSessionFactory().getStatistics();
+ log.info(stats.toString());
+ assertEquals(item.getDescription(), found.getDescription());
+ assertEquals(0, stats.getSecondLevelCacheMissCount());
+ assertEquals(1, stats.getSecondLevelCacheHitCount());
+ s.delete(found);
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ }
- s = openSession();
- Item found = (Item) s.load(Item.class, item.getId());
- System.out.println(stats);
- assertEquals(item.getDescription(), found.getDescription());
- assertEquals(0, stats.getSecondLevelCacheMissCount());
- assertEquals(1, stats.getSecondLevelCacheHitCount());
- s.delete(found);
- s.close();
- }
-
- public void testCollectionCache() {
+ public void testCollectionCache() throws Exception {
Item item = new Item("chris", "Chris's Item");
Item another = new Item("another", "Owned Item");
item.addItem(another);
- Session s = openSession();
- s.getTransaction().begin();
- s.persist(item);
- s.persist(another);
- s.getTransaction().commit();
- s.close();
+ beginTx();
+ try {
+ Session s = openSession();
+ s.getTransaction().begin();
+ s.persist(item);
+ s.persist(another);
+ s.getTransaction().commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- s = openSession();
- Statistics stats = s.getSessionFactory().getStatistics();
- Item loaded = (Item) s.load(Item.class, item.getId());
- assertEquals(1, loaded.getItems().size());
- s.close();
+ beginTx();
+ try {
+ Session s = openSession();
+ Item loaded = (Item) s.load(Item.class, item.getId());
+ assertEquals(1, loaded.getItems().size());
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- s = openSession();
- SecondLevelCacheStatistics cStats = stats.getSecondLevelCacheStatistics(Item.class.getName() + ".items");
- Item loadedWithCachedCollection = (Item) s.load(Item.class, item.getId());
- stats.logSummary();
- assertEquals(item.getName(), loadedWithCachedCollection.getName());
- assertEquals(item.getItems().size(), loadedWithCachedCollection.getItems().size());
- assertEquals(1, cStats.getHitCount());
- Map cacheEntries = cStats.getEntries();
- assertEquals(1, cacheEntries.size());
- s.close();
+ beginTx();
+ try {
+ Session s = openSession();
+ Statistics stats = s.getSessionFactory().getStatistics();
+ SecondLevelCacheStatistics cStats = stats.getSecondLevelCacheStatistics(Item.class.getName() + ".items");
+ Item loadedWithCachedCollection = (Item) s.load(Item.class, item.getId());
+ stats.logSummary();
+ assertEquals(item.getName(), loadedWithCachedCollection.getName());
+ assertEquals(item.getItems().size(), loadedWithCachedCollection.getItems().size());
+ assertEquals(1, cStats.getHitCount());
+ Map cacheEntries = cStats.getEntries();
+ assertEquals(1, cacheEntries.size());
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
}
- public void testStaleWritesLeaveCacheConsistent() {
- Session s = openSession();
- Transaction txn = s.beginTransaction();
- VersionedItem item = new VersionedItem();
- item.setName("steve");
- item.setDescription("steve's item");
- s.save(item);
- txn.commit();
- s.close();
+ public void testStaleWritesLeaveCacheConsistent() throws Exception {
+ VersionedItem item = null;
+ Transaction txn = null;
+ Session s = null;
+ beginTx();
+ try {
+ s = openSession();
+ txn = s.beginTransaction();
+ item = new VersionedItem();
+ item.setName("steve");
+ item.setDescription("steve's item");
+ s.save(item);
+ txn.commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
Long initialVersion = item.getVersion();
// manually revert the version property
item.setVersion(new Long(item.getVersion().longValue() - 1));
+ beginTx();
try {
- s = openSession();
- txn = s.beginTransaction();
- s.update(item);
- txn.commit();
- s.close();
- fail("expected stale write to fail");
- } catch (Throwable expected) {
- // expected behavior here
- if (txn != null) {
- try {
- txn.rollback();
- } catch (Throwable ignore) {
- }
- }
+ s = openSession();
+ txn = s.beginTransaction();
+ s.update(item);
+ txn.commit();
+ fail("expected stale write to fail");
+ } catch (Exception e) {
+ setRollbackOnlyTxExpected(e);
} finally {
- if (s != null && s.isOpen()) {
- try {
- s.close();
- } catch (Throwable ignore) {
- }
- }
+ commitOrRollbackTx();
+ if (s != null && s.isOpen()) {
+ try {
+ s.close();
+ } catch (Throwable ignore) {
+ }
+ }
}
// check the version value in the cache...
@@ -116,24 +164,42 @@
cachedVersionValue = (Long) ((CacheEntry) entry).getVersion();
assertEquals(initialVersion.longValue(), cachedVersionValue.longValue());
- // cleanup
- s = openSession();
- txn = s.beginTransaction();
- item = (VersionedItem) s.load(VersionedItem.class, item.getId());
- s.delete(item);
- txn.commit();
- s.close();
+ beginTx();
+ try {
+ // cleanup
+ s = openSession();
+ txn = s.beginTransaction();
+ item = (VersionedItem) s.load(VersionedItem.class, item.getId());
+ s.delete(item);
+ txn.commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
}
- public void testQueryCacheInvalidation() {
- Session s = openSession();
- Transaction t = s.beginTransaction();
- Item i = new Item();
- i.setName("widget");
- i.setDescription("A really top-quality, full-featured widget.");
- s.persist(i);
- t.commit();
- s.close();
+ public void testQueryCacheInvalidation() throws Exception {
+ Session s = null;
+ Transaction t = null;
+ Item i = null;
+
+ beginTx();
+ try {
+ s = openSession();
+ t = s.beginTransaction();
+ i = new Item();
+ i.setName("widget");
+ i.setDescription("A really top-quality, full-featured widget.");
+ s.persist(i);
+ t.commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
SecondLevelCacheStatistics slcs = s.getSessionFactory().getStatistics().getSecondLevelCacheStatistics(Item.class.getName());
@@ -141,18 +207,22 @@
assertEquals(slcs.getElementCountInMemory(), 1);
assertEquals(slcs.getEntries().size(), 1);
- s = openSession();
- t = s.beginTransaction();
- i = (Item) s.get(Item.class, i.getId());
+ beginTx();
+ try {
+ s = openSession();
+ t = s.beginTransaction();
+ i = (Item) s.get(Item.class, i.getId());
+ assertEquals(slcs.getHitCount(), 1);
+ assertEquals(slcs.getMissCount(), 0);
+ i.setDescription("A bog standard item");
+ t.commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- assertEquals(slcs.getHitCount(), 1);
- assertEquals(slcs.getMissCount(), 0);
-
- i.setDescription("A bog standard item");
-
- t.commit();
- s.close();
-
assertEquals(slcs.getPutCount(), 2);
CacheEntry entry = (CacheEntry) slcs.getEntries().get(i.getId());
@@ -160,32 +230,61 @@
assertTrue(ser[0].equals("widget"));
assertTrue(ser[1].equals("A bog standard item"));
- // cleanup
- s = openSession();
- t = s.beginTransaction();
- s.delete(i);
- t.commit();
- s.close();
+ beginTx();
+ try {
+ // cleanup
+ s = openSession();
+ t = s.beginTransaction();
+ s.delete(i);
+ t.commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
}
- public void testQueryCache() {
+ public void testQueryCache() throws Exception {
+ Session s = null;
Item item = new Item("chris", "Chris's Item");
+
+ beginTx();
+ try {
+ s = openSession();
+ s.getTransaction().begin();
+ s.persist(item);
+ s.getTransaction().commit();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- Session s = openSession();
- s.getTransaction().begin();
- s.persist(item);
- s.getTransaction().commit();
- s.close();
+ beginTx();
+ try {
+ s = openSession();
+ s.createQuery("from Item").setCacheable(true).list();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
- s = openSession();
- s.createQuery("from Item").setCacheable(true).list();
- s.close();
-
- s = openSession();
- Statistics stats = s.getSessionFactory().getStatistics();
- s.createQuery("from Item").setCacheable(true).list();
- assertEquals(1, stats.getQueryCacheHitCount());
- s.createQuery("delete from Item").executeUpdate();
- s.close();
+ beginTx();
+ try {
+ s = openSession();
+ Statistics stats = s.getSessionFactory().getStatistics();
+ s.createQuery("from Item").setCacheable(true).list();
+ assertEquals(1, stats.getQueryCacheHitCount());
+ s.createQuery("delete from Item").executeUpdate();
+ s.close();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
}
}
Added: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java (rev 0)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/ConcurrentWriteTest.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,513 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cache.infinispan.functional;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.transaction.TransactionManager;
+
+import org.hibernate.FlushMode;
+import org.hibernate.Session;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.infinispan.InfinispanRegionFactory;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.stat.SecondLevelCacheStatistics;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeTestCase;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeConnectionProviderImpl;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeTransactionManagerLookup;
+import org.hibernate.transaction.TransactionManagerLookup;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ *
+ * @author nikita_tovstoles(a)mba.berkeley.edu
+ * @author Galder Zamarreño
+ */
+public class ConcurrentWriteTest extends SingleNodeTestCase {
+ private static final Log log = LogFactory.getLog(ConcurrentWriteTest.class);
+
+ /**
+ * when USER_COUNT==1, tests pass, when >4 tests fail
+ */
+ private static final int USER_COUNT = 5;
+ private static final int ITERATION_COUNT = 150;
+ private static final int THINK_TIME_MILLIS = 10;
+ private static final long LAUNCH_INTERVAL_MILLIS = 10;
+ private static final Random random = new Random();
+
+ /**
+ * kill switch used to stop all users when one fails
+ */
+ private static volatile boolean TERMINATE_ALL_USERS = false;
+
+ /**
+ * collection of IDs of all customers participating in this test
+ */
+ private Set<Integer> customerIDs = new HashSet<Integer>();
+
+ private TransactionManager tm;
+
+ public ConcurrentWriteTest(String x) {
+ super(x);
+ }
+
+ @Override
+ protected TransactionManager getTransactionManager() {
+ return DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.LOCAL);
+ }
+
+ @Override
+ protected Class<? extends RegionFactory> getCacheRegionFactory() {
+ return InfinispanRegionFactory.class;
+ }
+
+ @Override
+ protected Class<? extends ConnectionProvider> getConnectionProviderClass() {
+ return DualNodeConnectionProviderImpl.class;
+ }
+
+ @Override
+ protected Class<? extends TransactionManagerLookup> getTransactionManagerLookupClass() {
+ return DualNodeTransactionManagerLookup.class;
+ }
+
+ /**
+ * test that DB can be queried
+ *
+ * @throws java.lang.Exception
+ */
+ public void testPingDb() throws Exception {
+ try {
+ beginTx();
+ getEnvironment().getSessionFactory().getCurrentSession().createQuery("from " + Customer.class.getName()).list();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+// setRollbackOnly();
+// fail("failed to query DB; exception=" + e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ }
+
+ @Override
+ protected void prepareTest() throws Exception {
+ super.prepareTest();
+ TERMINATE_ALL_USERS = false;
+ }
+
+ @Override
+ protected void cleanupTest() throws Exception {
+ try {
+ super.cleanupTest();
+ } finally {
+ cleanup();
+ // DualNodeJtaTransactionManagerImpl.cleanupTransactions();
+ // DualNodeJtaTransactionManagerImpl.cleanupTransactionManagers();
+ }
+ }
+
+ @Override
+ public void configure(Configuration cfg) {
+ super.configure(cfg);
+ cfg.setProperty(DualNodeTestCase.NODE_ID_PROP, DualNodeTestCase.LOCAL);
+ }
+
+ @Override
+ protected boolean getUseQueryCache() {
+ return true;
+ }
+
+ public void testSingleUser() throws Exception {
+ // setup
+ Customer customer = createCustomer(0);
+ final Integer customerId = customer.getId();
+ getCustomerIDs().add(customerId);
+
+ assertNull("contact exists despite not being added", getFirstContact(customerId));
+
+ // check that cache was hit
+ SecondLevelCacheStatistics customerSlcs = getEnvironment().getSessionFactory()
+ .getStatistics().getSecondLevelCacheStatistics(Customer.class.getName());
+ assertEquals(customerSlcs.getPutCount(), 1);
+ assertEquals(customerSlcs.getElementCountInMemory(), 1);
+ assertEquals(customerSlcs.getEntries().size(), 1);
+
+ SecondLevelCacheStatistics contactsCollectionSlcs = getEnvironment().getSessionFactory()
+ .getStatistics().getSecondLevelCacheStatistics(Customer.class.getName() + ".contacts");
+ assertEquals(1, contactsCollectionSlcs.getPutCount());
+ assertEquals(1, contactsCollectionSlcs.getElementCountInMemory());
+ assertEquals(1, contactsCollectionSlcs.getEntries().size());
+
+ final Contact contact = addContact(customerId);
+ assertNotNull("contact returned by addContact is null", contact);
+ assertEquals("Customer.contacts cache was not invalidated after addContact", 0,
+ contactsCollectionSlcs.getElementCountInMemory());
+
+ assertNotNull("Contact missing after successful add call", getFirstContact(customerId));
+
+ // read everyone's contacts
+ readEveryonesFirstContact();
+
+ removeContact(customerId);
+ assertNull("contact still exists after successful remove call", getFirstContact(customerId));
+
+ }
+
+// /**
+// * TODO: This will fail until ISPN-??? has been fixed.
+// *
+// * @throws Exception
+// */
+// public void testManyUsers() throws Throwable {
+// try {
+// // setup - create users
+// for (int i = 0; i < USER_COUNT; i++) {
+// Customer customer = createCustomer(0);
+// getCustomerIDs().add(customer.getId());
+// }
+// assertEquals("failed to create enough Customers", USER_COUNT, getCustomerIDs().size());
+//
+// final ExecutorService executor = Executors.newFixedThreadPool(USER_COUNT);
+//
+// CyclicBarrier barrier = new CyclicBarrier(USER_COUNT + 1);
+// List<Future<Void>> futures = new ArrayList<Future<Void>>(USER_COUNT);
+// for (Integer customerId : getCustomerIDs()) {
+// Future<Void> future = executor.submit(new UserRunner(customerId, barrier));
+// futures.add(future);
+// Thread.sleep(LAUNCH_INTERVAL_MILLIS); // rampup
+// }
+//// barrier.await(); // wait for all threads to be ready
+// barrier.await(45, TimeUnit.SECONDS); // wait for all threads to finish
+// log.info("All threads finished, let's shutdown the executor and check whether any exceptions were reported");
+// for (Future<Void> future : futures) future.get();
+// log.info("All future gets checked");
+// } catch (Throwable t) {
+// log.error("Error running test", t);
+// throw t;
+// }
+// }
+
+ public void cleanup() throws Exception {
+ getCustomerIDs().clear();
+ String deleteContactHQL = "delete from Contact";
+ String deleteCustomerHQL = "delete from Customer";
+ beginTx();
+ try {
+ Session session = getEnvironment().getSessionFactory().getCurrentSession();
+ session.createQuery(deleteContactHQL).setFlushMode(FlushMode.AUTO).executeUpdate();
+ session.createQuery(deleteCustomerHQL).setFlushMode(FlushMode.AUTO).executeUpdate();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ }
+
+ private Customer createCustomer(int nameSuffix) throws Exception {
+ Customer customer = null;
+ beginTx();
+ try {
+ customer = new Customer();
+ customer.setName("customer_" + nameSuffix);
+ customer.setContacts(new HashSet<Contact>());
+ getEnvironment().getSessionFactory().getCurrentSession().persist(customer);
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ return customer;
+ }
+
+ /**
+ * read first contact of every Customer participating in this test. this forces concurrent cache
+ * writes of Customer.contacts Collection cache node
+ *
+ * @return who cares
+ * @throws java.lang.Exception
+ */
+ private void readEveryonesFirstContact() throws Exception {
+ beginTx();
+ try {
+ for (Integer customerId : getCustomerIDs()) {
+ if (TERMINATE_ALL_USERS) {
+ setRollbackOnlyTx();
+ return;
+ }
+ Customer customer = (Customer) getEnvironment().getSessionFactory().getCurrentSession().load(Customer.class, customerId);
+ Set<Contact> contacts = customer.getContacts();
+ if (!contacts.isEmpty()) {
+ contacts.iterator().next();
+ }
+ }
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ }
+
+ /**
+ * -load existing Customer -get customer's contacts; return 1st one
+ *
+ * @param customerId
+ * @return first Contact or null if customer has none
+ */
+ private Contact getFirstContact(Integer customerId) throws Exception {
+ assert customerId != null;
+ Contact firstContact = null;
+ beginTx();
+ try {
+ final Customer customer = (Customer) getEnvironment().getSessionFactory()
+ .getCurrentSession().load(Customer.class, customerId);
+ Set<Contact> contacts = customer.getContacts();
+ firstContact = contacts.isEmpty() ? null : contacts.iterator().next();
+ if (TERMINATE_ALL_USERS)
+ setRollbackOnlyTx();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ return firstContact;
+ }
+
+ /**
+ * -load existing Customer -create a new Contact and add to customer's contacts
+ *
+ * @param customerId
+ * @return added Contact
+ */
+ private Contact addContact(Integer customerId) throws Exception {
+ assert customerId != null;
+ Contact contact = null;
+ beginTx();
+ try {
+ final Customer customer = (Customer) getEnvironment().getSessionFactory()
+ .getCurrentSession().load(Customer.class, customerId);
+ contact = new Contact();
+ contact.setName("contact name");
+ contact.setTlf("wtf is tlf?");
+ contact.setCustomer(customer);
+ customer.getContacts().add(contact);
+ // assuming contact is persisted via cascade from customer
+ if (TERMINATE_ALL_USERS)
+ setRollbackOnlyTx();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ return contact;
+ }
+
+ /**
+ * remove existing 'contact' from customer's list of contacts
+ *
+ * @param contact
+ * contact to remove from customer's contacts
+ * @param customerId
+ * @throws IllegalStateException
+ * if customer does not own a contact
+ */
+ private void removeContact(Integer customerId) throws Exception {
+ assert customerId != null;
+
+ beginTx();
+ try {
+ Customer customer = (Customer) getEnvironment().getSessionFactory().getCurrentSession()
+ .load(Customer.class, customerId);
+ Set<Contact> contacts = customer.getContacts();
+ if (contacts.size() != 1) {
+ throw new IllegalStateException("can't remove contact: customer id=" + customerId
+ + " expected exactly 1 contact, " + "actual count=" + contacts.size());
+ }
+
+ Contact contact = contacts.iterator().next();
+ contacts.remove(contact);
+ contact.setCustomer(null);
+
+ // explicitly delete Contact because hbm has no 'DELETE_ORPHAN' cascade?
+ // getEnvironment().getSessionFactory().getCurrentSession().delete(contact); //appears to
+ // not be needed
+
+ // assuming contact is persisted via cascade from customer
+
+ if (TERMINATE_ALL_USERS)
+ setRollbackOnlyTx();
+ } catch (Exception e) {
+ setRollbackOnlyTx(e);
+ } finally {
+ commitOrRollbackTx();
+ }
+ }
+
+ /**
+ * @return the customerIDs
+ */
+ public Set<Integer> getCustomerIDs() {
+ return customerIDs;
+ }
+
+ private String statusOfRunnersToString(Set<UserRunner> runners) {
+ assert runners != null;
+
+ StringBuilder sb = new StringBuilder("TEST CONFIG [userCount=" + USER_COUNT
+ + ", iterationsPerUser=" + ITERATION_COUNT + ", thinkTimeMillis="
+ + THINK_TIME_MILLIS + "] " + " STATE of UserRunners: ");
+
+ for (UserRunner r : runners) {
+ sb.append(r.toString() + System.getProperty("line.separator"));
+ }
+ return sb.toString();
+ }
+
+ class UserRunner implements Callable<Void> {
+ private final CyclicBarrier barrier;
+ final private Integer customerId;
+ private int completedIterations = 0;
+ private Throwable causeOfFailure;
+
+ public UserRunner(Integer cId, CyclicBarrier barrier) {
+ assert cId != null;
+ this.customerId = cId;
+ this.barrier = barrier;
+ }
+
+ private boolean contactExists() throws Exception {
+ return getFirstContact(customerId) != null;
+ }
+
+ public Void call() throws Exception {
+ // name this thread for easier log tracing
+ Thread.currentThread().setName("UserRunnerThread-" + getCustomerId());
+ log.info("Wait for all executions paths to be ready to perform calls");
+ try {
+// barrier.await();
+ for (int i = 0; i < ITERATION_COUNT && !TERMINATE_ALL_USERS; i++) {
+ if (contactExists())
+ throw new IllegalStateException("contact already exists before add, customerId=" + customerId);
+ addContact(customerId);
+ thinkRandomTime();
+ if (!contactExists())
+ throw new IllegalStateException("contact missing after successful add, customerId=" + customerId);
+ thinkRandomTime();
+ // read everyone's contacts
+ readEveryonesFirstContact();
+ thinkRandomTime();
+ removeContact(customerId);
+ if (contactExists())
+ throw new IllegalStateException("contact still exists after successful remove call, customerId=" + customerId);
+ thinkRandomTime();
+ ++completedIterations;
+ if (log.isTraceEnabled()) log.trace("Iteration completed {0}", completedIterations);
+ }
+ } catch (Throwable t) {
+ TERMINATE_ALL_USERS = true;
+ log.error("Error", t);
+ throw new Exception(t);
+ // rollback current transaction if any
+ // really should not happen since above methods all follow begin-commit-rollback pattern
+ // try {
+ // if
+ // (DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestUtil.LOCAL).getTransaction()
+ // != null) {
+ // DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestUtil.LOCAL).rollback();
+ // }
+ // } catch (SystemException ex) {
+ // throw new RuntimeException("failed to rollback tx", ex);
+ // }
+ } finally {
+ log.info("Wait for all execution paths to finish");
+ barrier.await();
+ }
+ return null;
+ }
+
+ public boolean isSuccess() {
+ return ITERATION_COUNT == getCompletedIterations();
+ }
+
+ public int getCompletedIterations() {
+ return completedIterations;
+ }
+
+ public Throwable getCauseOfFailure() {
+ return causeOfFailure;
+ }
+
+ public Integer getCustomerId() {
+ return customerId;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "[customerId=" + getCustomerId() + " iterationsCompleted="
+ + getCompletedIterations() + " completedAll=" + isSuccess() + " causeOfFailure="
+ + (this.causeOfFailure != null ? getStackTrace(causeOfFailure) : "") + "] ";
+ }
+ }
+
+ public static String getStackTrace(Throwable throwable) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ throwable.printStackTrace(pw);
+ return sw.getBuffer().toString();
+ }
+
+ /**
+ * sleep between 0 and THINK_TIME_MILLIS.
+ *
+ * @throws RuntimeException
+ * if sleep is interrupted or TERMINATE_ALL_USERS flag was set to true i n the
+ * meantime
+ */
+ private void thinkRandomTime() {
+ try {
+ Thread.sleep(random.nextInt(THINK_TIME_MILLIS));
+ } catch (InterruptedException ex) {
+ throw new RuntimeException("sleep interrupted", ex);
+ }
+
+ if (TERMINATE_ALL_USERS) {
+ throw new RuntimeException("told to terminate (because a UserRunner had failed)");
+ }
+ }
+
+}
Copied: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java (from rev 17976, core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/AbstractFunctionalTestCase.java)
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java (rev 0)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/SingleNodeTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,121 @@
+package org.hibernate.test.cache.infinispan.functional;
+
+import java.util.Map;
+
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.infinispan.InfinispanRegionFactory;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.stat.SecondLevelCacheStatistics;
+import org.hibernate.stat.Statistics;
+import org.hibernate.transaction.CMTTransactionFactory;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.transaction.TransactionManagerLookup;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ * @author Galder Zamarreño
+ * @since 3.5
+ */
+public abstract class SingleNodeTestCase extends FunctionalTestCase {
+ private static final Log log = LogFactory.getLog(SingleNodeTestCase.class);
+ private final TransactionManager tm;
+
+ public SingleNodeTestCase(String string) {
+ super(string);
+ tm = getTransactionManager();
+ }
+
+ protected TransactionManager getTransactionManager() {
+ try {
+ return getTransactionManagerLookupClass().newInstance().getTransactionManager(null);
+ } catch (Exception e) {
+ log.error("Error", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public String[] getMappings() {
+ return new String[] {
+ "cache/infinispan/functional/Item.hbm.xml",
+ "cache/infinispan/functional/Customer.hbm.xml",
+ "cache/infinispan/functional/Contact.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 Class<? extends TransactionManagerLookup> getTransactionManagerLookupClass() {
+ return org.hibernate.test.cache.infinispan.tm.XaTransactionManagerLookup.class;
+ }
+
+ protected boolean getUseQueryCache() {
+ return true;
+ }
+
+ 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, String.valueOf(getUseQueryCache()));
+ cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
+ cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
+ cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
+ cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
+ }
+
+ public void testEmptySecondLevelCacheEntry() throws Exception {
+ getSessions().getCache().evictEntityRegion(Item.class.getName());
+ Statistics stats = getSessions().getStatistics();
+ stats.clear();
+ SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics(Item.class.getName() + ".items");
+ Map cacheEntries = statistics.getEntries();
+ assertEquals(0, cacheEntries.size());
+ }
+
+ protected void beginTx() throws Exception {
+ tm.begin();
+ }
+
+ protected void setRollbackOnlyTx() throws Exception {
+ tm.setRollbackOnly();
+ }
+
+ protected void setRollbackOnlyTx(Exception e) throws Exception {
+ log.error("Error", e);
+ tm.setRollbackOnly();
+ throw e;
+ }
+
+ protected void setRollbackOnlyTxExpected(Exception e) throws Exception {
+ log.debug("Expected behaivour", e);
+ tm.setRollbackOnly();
+ }
+
+ protected void commitOrRollbackTx() throws Exception {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
+ }
+
+}
\ No newline at end of file
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/bulk/BulkOperationsTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -25,20 +25,25 @@
import java.util.List;
import java.util.Set;
+import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.hibernate.FlushMode;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.classic.Session;
+import org.hibernate.connection.ConnectionProvider;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.test.cache.infinispan.functional.Contact;
import org.hibernate.test.cache.infinispan.functional.Customer;
import org.hibernate.transaction.CMTTransactionFactory;
+import org.hibernate.transaction.TransactionFactory;
import org.hibernate.transaction.TransactionManagerLookup;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* BulkOperationsTestCase.
@@ -47,9 +52,8 @@
* @since 3.5
*/
public class BulkOperationsTestCase extends FunctionalTestCase {
+ private static final Log log = LogFactory.getLog(BulkOperationsTestCase.class);
- private static final Logger log = LoggerFactory.getLogger(BulkOperationsTestCase.class);
-
private TransactionManager tm;
public BulkOperationsTestCase(String string) {
@@ -66,11 +70,15 @@
return "transactional";
}
- protected Class getTransactionFactoryClass() {
+ protected Class<? extends RegionFactory> getCacheRegionFactory() {
+ return InfinispanRegionFactory.class;
+ }
+
+ protected Class<? extends TransactionFactory> getTransactionFactoryClass() {
return CMTTransactionFactory.class;
}
- protected Class getConnectionProviderClass() {
+ protected Class<? extends ConnectionProvider> getConnectionProviderClass() {
return org.hibernate.test.cache.infinispan.tm.XaConnectionProvider.class;
}
@@ -80,20 +88,17 @@
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.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass()
- .getName());
-
- Class transactionFactory = getTransactionFactoryClass();
- cfg.setProperty(Environment.TRANSACTION_STRATEGY, transactionFactory.getName());
+ cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
+ cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
}
public void testBulkOperations() throws Throwable {
- System.out.println("*** testBulkOperations()");
+ log.info("*** testBulkOperations()");
boolean cleanedUp = false;
try {
tm = getTransactionManagerLookupClass().newInstance().getTransactionManager(null);
@@ -166,13 +171,14 @@
log.debug("Create 10 contacts");
tm.begin();
try {
- for (int i = 0; i < 10; i++)
- createCustomer(i);
- tm.commit();
+ for (int i = 0; i < 10; i++) createCustomer(i);
} catch (Exception e) {
log.error("Unable to create customer", e);
- tm.rollback();
+ tm.setRollbackOnly();
throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
}
}
@@ -183,19 +189,25 @@
tm.begin();
try {
-
Session session = getSessions().getCurrentSession();
int rowsAffected = session.createQuery(deleteHQL).setFlushMode(FlushMode.AUTO)
.setParameter("cName", "Red Hat").executeUpdate();
tm.commit();
return rowsAffected;
} catch (Exception e) {
- try {
- tm.rollback();
- } catch (Exception ee) {
- // ignored
+ log.error("Unable to delete contac", e);
+ tm.setRollbackOnly();
+ throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) {
+ tm.commit();
+ } else {
+ try {
+ tm.rollback();
+ } catch (Exception ee) {
+ // ignored
+ }
}
- throw e;
}
}
@@ -210,11 +222,14 @@
Session session = getSessions().getCurrentSession();
List results = session.createQuery(selectHQL).setFlushMode(FlushMode.AUTO).setParameter(
"cName", customerName).list();
- tm.commit();
return results;
} catch (Exception e) {
- tm.rollback();
+ log.error("Unable to get contacts by customer", e);
+ tm.setRollbackOnly();
throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
}
}
@@ -224,15 +239,17 @@
tm.begin();
try {
-
Session session = getSessions().getCurrentSession();
List results = session.createQuery(selectHQL).setFlushMode(FlushMode.AUTO).setParameter(
"cTLF", tlf).list();
- tm.commit();
return results;
} catch (Exception e) {
- tm.rollback();
+ log.error("Unable to get contacts", e);
+ tm.setRollbackOnly();
throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
}
}
@@ -243,11 +260,14 @@
Session session = getSessions().getCurrentSession();
int rowsAffected = session.createQuery(updateHQL).setFlushMode(FlushMode.AUTO)
.setParameter("cNewTLF", newTLF).setParameter("cName", name).executeUpdate();
- tm.commit();
return rowsAffected;
} catch (Exception e) {
- tm.rollback();
+ log.error("Unable to update contacts", e);
+ tm.setRollbackOnly();
throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
}
}
@@ -262,25 +282,30 @@
list.get(0).setTlf(newTLF);
int rowsAffected = session.createQuery(updateHQL).setFlushMode(FlushMode.AUTO)
.setParameter("cNewTLF", newTLF).setParameter("cName", name).executeUpdate();
- tm.commit();
return rowsAffected;
} catch (Exception e) {
- tm.rollback();
+ log.error("Unable to update contacts with one manual", 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 = getSessions().getCurrentSession();
Contact contact = (Contact) session.get(Contact.class, id);
- tm.commit();
return contact;
} catch (Exception e) {
- tm.rollback();
+ log.error("Unable to get contact", e);
+ tm.setRollbackOnly();
throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) tm.commit();
+ else tm.rollback();
}
}
@@ -292,15 +317,21 @@
Session session = getSessions().getCurrentSession();
session.createQuery(deleteContactHQL).setFlushMode(FlushMode.AUTO).executeUpdate();
session.createQuery(deleteCustomerHQL).setFlushMode(FlushMode.AUTO).executeUpdate();
- tm.commit();
} catch (Exception e) {
- if (!ignore) {
- try {
- tm.rollback();
- } catch (Exception ee) {
- // ignored
+ log.error("Unable to get contact", e);
+ tm.setRollbackOnly();
+ throw e;
+ } finally {
+ if (tm.getStatus() == Status.STATUS_ACTIVE) {
+ tm.commit();
+ } else {
+ if (!ignore) {
+ try {
+ tm.rollback();
+ } catch (Exception ee) {
+ // ignored
+ }
}
- throw e;
}
}
}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/ClassLoaderTestDAO.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/ClassLoaderTestDAO.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/ClassLoaderTestDAO.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -30,8 +30,8 @@
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* Comment
@@ -39,7 +39,7 @@
* @author Brian Stansberry
*/
public class ClassLoaderTestDAO {
- private static final Logger log = LoggerFactory.getLogger(ClassLoaderTestDAO.class);
+ private static final Log log = LogFactory.getLog(ClassLoaderTestDAO.class);
private SessionFactory sessionFactory;
private TransactionManager tm;
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/IsolatedClassLoaderTest.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/IsolatedClassLoaderTest.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/classloader/IsolatedClassLoaderTest.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -30,7 +30,7 @@
import org.hibernate.cache.StandardQueryCache;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Configuration;
-import org.hibernate.test.cache.infinispan.functional.cluster.AbstractDualNodeTestCase;
+import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeTestCase;
import org.hibernate.test.cache.infinispan.functional.cluster.ClusterAwareRegionFactory;
import org.hibernate.test.cache.infinispan.functional.cluster.DualNodeJtaTransactionManagerImpl;
import org.infinispan.Cache;
@@ -51,7 +51,7 @@
* @author Galder Zamarreño
* @since 3.5
*/
-public class IsolatedClassLoaderTest extends AbstractDualNodeTestCase {
+public class IsolatedClassLoaderTest extends DualNodeTestCase {
public static final String OUR_PACKAGE = IsolatedClassLoaderTest.class.getPackage().getName();
@@ -119,11 +119,11 @@
public void testIsolatedSetup() throws Exception {
// Bind a listener to the "local" cache
// Our region factory makes its CacheManager available to us
- CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.LOCAL);
+ CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.LOCAL);
Cache localReplicatedCache = localManager.getCache("replicated-entity");
// Bind a listener to the "remote" cache
- CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.REMOTE);
+ CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.REMOTE);
Cache remoteReplicatedCache = remoteManager.getCache("replicated-entity");
ClassLoader cl = Thread.currentThread().getContextClassLoader();
@@ -163,20 +163,20 @@
protected void queryTest(boolean useNamedRegion) throws Exception {
// Bind a listener to the "local" cache
// Our region factory makes its CacheManager available to us
- CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.LOCAL);
+ CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.LOCAL);
localQueryCache = localManager.getCache("replicated-query");
localQueryListener = new CacheAccessListener();
localQueryCache.addListener(localQueryListener);
- TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.LOCAL);
+ TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.LOCAL);
// Bind a listener to the "remote" cache
- CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.REMOTE);
+ CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.REMOTE);
remoteQueryCache = remoteManager.getCache("replicated-query");
remoteQueryListener = new CacheAccessListener();
remoteQueryCache.addListener(remoteQueryListener);
- TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.REMOTE);
+ TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.REMOTE);
SessionFactory localFactory = getEnvironment().getSessionFactory();
SessionFactory remoteFactory = getSecondNodeEnvironment().getSessionFactory();
Deleted: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/AbstractDualNodeTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/AbstractDualNodeTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/AbstractDualNodeTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -1,241 +0,0 @@
-/*
- * 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.cluster;
-
-import java.util.Set;
-
-import org.hibernate.Session;
-import org.hibernate.cache.infinispan.util.CacheHelper;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.cfg.Mappings;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.junit.functional.ExecutionEnvironment;
-import org.hibernate.junit.functional.FunctionalTestCase;
-import org.hibernate.transaction.CMTTransactionFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * AbstractDualNodeTestCase.
- *
- * @author Galder Zamarreño
- * @since 3.5
- */
-public abstract class AbstractDualNodeTestCase extends FunctionalTestCase {
-
- private static final Logger log = LoggerFactory.getLogger(AbstractDualNodeTestCase.class);
- public static final String NODE_ID_PROP = "hibernate.test.cluster.node.id";
- public static final String LOCAL = "local";
- public static final String REMOTE = "remote";
- private ExecutionEnvironment secondNodeEnvironment;
- private Session secondNodeSession;
-
- public AbstractDualNodeTestCase(String string) {
- super(string);
- }
-
- 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 getCacheRegionFactory() {
- return ClusterAwareRegionFactory.class;
- }
-
- @Override
- public void configure(Configuration cfg) {
- standardConfigure(cfg);
- configureFirstNode(cfg);
- }
-
- @Override
- protected void prepareTest() throws Exception {
- log.info("Building second node locally managed execution env");
- secondNodeEnvironment = new ExecutionEnvironment(new SecondNodeSettings());
- secondNodeEnvironment.initialize();
- super.prepareTest();
- }
-
- @Override
- protected void runTest() throws Throwable {
- try {
- super.runTest();
- } finally {
- if ( secondNodeSession != null && secondNodeSession.isOpen() ) {
- if ( secondNodeSession.isConnected() ) {
- secondNodeSession.connection().rollback();
- }
- secondNodeSession.close();
- secondNodeSession = null;
- fail( "unclosed session" );
- } else {
- secondNodeSession = null;
- }
-
- }
- }
-
- @Override
- protected void cleanupTest() throws Exception {
- try {
- super.cleanupTest();
-
- log.info( "Destroying second node locally managed execution env" );
- secondNodeEnvironment.complete();
- secondNodeEnvironment = null;
- } finally {
- cleanupTransactionManagement();
- }
- }
-
- protected void cleanupTransactionManagement() {
- DualNodeJtaTransactionManagerImpl.cleanupTransactions();
- DualNodeJtaTransactionManagerImpl.cleanupTransactionManagers();
- }
-
- public ExecutionEnvironment getSecondNodeEnvironment() {
- return secondNodeEnvironment;
- }
-
- protected Class getConnectionProviderClass() {
- return DualNodeConnectionProviderImpl.class;
- }
-
- protected Class getTransactionManagerLookupClass() {
- return DualNodeTransactionManagerLookup.class;
- }
-
- protected Class getTransactionFactoryClass() {
- return CMTTransactionFactory.class;
- }
-
- /**
- * Apply any node-specific configurations to our first node.
- *
- * @param the
- * Configuration to update.
- */
- protected void configureFirstNode(Configuration cfg) {
- cfg.setProperty(NODE_ID_PROP, LOCAL);
- }
-
- /**
- * Apply any node-specific configurations to our second node.
- *
- * @param the
- * Configuration to update.
- */
- protected void configureSecondNode(Configuration cfg) {
- cfg.setProperty(NODE_ID_PROP, REMOTE);
- }
-
- protected void sleep(long ms) {
- try {
- Thread.sleep(ms);
- }
- catch (InterruptedException e) {
- log.warn("Interrupted during sleep", e);
- }
- }
-
- protected void standardConfigure(Configuration cfg) {
- super.configure(cfg);
-
- cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
- cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
- cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
- cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
- }
-
- /**
- * Settings impl that delegates most calls to the DualNodeTestCase itself, but overrides the
- * configure method to allow separate cache settings for the second node.
- */
- public class SecondNodeSettings implements ExecutionEnvironment.Settings {
- private final AbstractDualNodeTestCase delegate;
-
- public SecondNodeSettings() {
- this.delegate = AbstractDualNodeTestCase.this;
- }
-
- /**
- * This is the important one -- we extend the delegate's work by adding second-node specific
- * settings
- */
- public void configure(Configuration arg0) {
- delegate.standardConfigure(arg0);
- configureSecondNode(arg0);
- }
-
- /**
- * Disable creating of schemas; we let the primary session factory do that to our shared
- * database.
- */
- public boolean createSchema() {
- return false;
- }
-
- /**
- * Disable creating of schemas; we let the primary session factory do that to our shared
- * database.
- */
- public boolean recreateSchemaAfterFailure() {
- return false;
- }
-
- public void afterConfigurationBuilt(Mappings arg0, Dialect arg1) {
- delegate.afterConfigurationBuilt(arg0, arg1);
- }
-
- public void afterSessionFactoryBuilt(SessionFactoryImplementor arg0) {
- delegate.afterSessionFactoryBuilt(arg0);
- }
-
- public boolean appliesTo(Dialect arg0) {
- return delegate.appliesTo(arg0);
- }
-
- public String getBaseForMappings() {
- return delegate.getBaseForMappings();
- }
-
- public String getCacheConcurrencyStrategy() {
- return delegate.getCacheConcurrencyStrategy();
- }
-
- public String[] getMappings() {
- return delegate.getMappings();
- }
-
- public boolean overrideCacheStrategy() {
- return delegate.overrideCacheStrategy();
- }
- }
-
-}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/ClusterAwareRegionFactory.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -34,8 +34,8 @@
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cfg.Settings;
import org.infinispan.manager.CacheManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* ClusterAwareRegionFactory.
@@ -45,7 +45,7 @@
*/
public class ClusterAwareRegionFactory implements RegionFactory {
- private static final Logger log = LoggerFactory.getLogger(ClusterAwareRegionFactory.class);
+ private static final Log log = LogFactory.getLog(ClusterAwareRegionFactory.class);
private static final Hashtable<String, CacheManager> cacheManagers = new Hashtable<String, CacheManager>();
private final InfinispanRegionFactory delegate = new InfinispanRegionFactory();
@@ -75,7 +75,7 @@
}
public void start(Settings settings, Properties properties) throws CacheException {
- cacheManagerName = properties.getProperty(AbstractDualNodeTestCase.NODE_ID_PROP);
+ cacheManagerName = properties.getProperty(DualNodeTestCase.NODE_ID_PROP);
CacheManager existing = getCacheManager(cacheManagerName);
locallyAdded = (existing == null);
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeConnectionProviderImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeConnectionProviderImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeConnectionProviderImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -47,9 +47,9 @@
}
public void configure(Properties props) throws HibernateException {
- nodeId = props.getProperty(AbstractDualNodeTestCase.NODE_ID_PROP);
+ nodeId = props.getProperty(DualNodeTestCase.NODE_ID_PROP);
if (nodeId == null)
- throw new HibernateException(AbstractDualNodeTestCase.NODE_ID_PROP + " not configured");
+ throw new HibernateException(DualNodeTestCase.NODE_ID_PROP + " not configured");
}
public Connection getConnection() throws SQLException {
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -42,8 +42,8 @@
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* SimpleJtaTransactionImpl variant that works with DualNodeTransactionManagerImpl.
@@ -51,7 +51,7 @@
* @author Brian Stansberry
*/
public class DualNodeJtaTransactionImpl implements Transaction {
- private static final Logger log = LoggerFactory.getLogger(DualNodeJtaTransactionImpl.class);
+ private static final Log log = LogFactory.getLog(DualNodeJtaTransactionImpl.class);
private int status;
private LinkedList synchronizations;
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionManagerImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionManagerImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeJtaTransactionManagerImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -35,8 +35,8 @@
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* Variant of SimpleJtaTransactionManagerImpl that doesn't use a VM-singleton, but rather a set of
@@ -46,7 +46,7 @@
*/
public class DualNodeJtaTransactionManagerImpl implements TransactionManager {
- private static final Logger log = LoggerFactory.getLogger(DualNodeJtaTransactionManagerImpl.class);
+ private static final Log log = LogFactory.getLog(DualNodeJtaTransactionManagerImpl.class);
private static final Hashtable INSTANCES = new Hashtable();
Copied: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java (from rev 17976, core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/AbstractDualNodeTestCase.java)
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java (rev 0)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -0,0 +1,243 @@
+/*
+ * 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.cluster;
+
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.Mappings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.junit.functional.ExecutionEnvironment;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.transaction.CMTTransactionFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ * AbstractDualNodeTestCase.
+ *
+ * @author Galder Zamarreño
+ * @since 3.5
+ */
+public abstract class DualNodeTestCase extends FunctionalTestCase {
+
+ private static final Log log = LogFactory.getLog(DualNodeTestCase.class);
+ public static final String NODE_ID_PROP = "hibernate.test.cluster.node.id";
+ public static final String LOCAL = "local";
+ public static final String REMOTE = "remote";
+ private ExecutionEnvironment secondNodeEnvironment;
+ private Session secondNodeSession;
+
+ public DualNodeTestCase(String string) {
+ super(string);
+ }
+
+ 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 getCacheRegionFactory() {
+ return ClusterAwareRegionFactory.class;
+ }
+
+ @Override
+ public void configure(Configuration cfg) {
+ standardConfigure(cfg);
+ configureFirstNode(cfg);
+ }
+
+ @Override
+ protected void prepareTest() throws Exception {
+ log.info("Building second node locally managed execution env");
+ secondNodeEnvironment = new ExecutionEnvironment(new SecondNodeSettings());
+ secondNodeEnvironment.initialize();
+ super.prepareTest();
+ }
+
+ @Override
+ protected void runTest() throws Throwable {
+ try {
+ super.runTest();
+ } finally {
+ if ( secondNodeSession != null && secondNodeSession.isOpen() ) {
+ if ( secondNodeSession.isConnected() ) {
+ secondNodeSession.connection().rollback();
+ }
+ secondNodeSession.close();
+ secondNodeSession = null;
+ fail( "unclosed session" );
+ } else {
+ secondNodeSession = null;
+ }
+
+ }
+ }
+
+ @Override
+ protected void cleanupTest() throws Exception {
+ try {
+ super.cleanupTest();
+
+ log.info( "Destroying second node locally managed execution env" );
+ secondNodeEnvironment.complete();
+ secondNodeEnvironment = null;
+ } finally {
+ cleanupTransactionManagement();
+ }
+ }
+
+ protected void cleanupTransactionManagement() {
+ DualNodeJtaTransactionManagerImpl.cleanupTransactions();
+ DualNodeJtaTransactionManagerImpl.cleanupTransactionManagers();
+ }
+
+ public ExecutionEnvironment getSecondNodeEnvironment() {
+ return secondNodeEnvironment;
+ }
+
+ protected Class getConnectionProviderClass() {
+ return DualNodeConnectionProviderImpl.class;
+ }
+
+ protected Class getTransactionManagerLookupClass() {
+ return DualNodeTransactionManagerLookup.class;
+ }
+
+ protected Class getTransactionFactoryClass() {
+ return CMTTransactionFactory.class;
+ }
+
+ /**
+ * Apply any node-specific configurations to our first node.
+ *
+ * @param the
+ * Configuration to update.
+ */
+ protected void configureFirstNode(Configuration cfg) {
+ cfg.setProperty(NODE_ID_PROP, LOCAL);
+ }
+
+ /**
+ * Apply any node-specific configurations to our second node.
+ *
+ * @param the
+ * Configuration to update.
+ */
+ protected void configureSecondNode(Configuration cfg) {
+ cfg.setProperty(NODE_ID_PROP, REMOTE);
+ }
+
+ protected void sleep(long ms) {
+ try {
+ Thread.sleep(ms);
+ }
+ catch (InterruptedException e) {
+ log.warn("Interrupted during sleep", e);
+ }
+ }
+
+ protected boolean getUseQueryCache() {
+ return true;
+ }
+
+ protected void standardConfigure(Configuration cfg) {
+ super.configure(cfg);
+
+ cfg.setProperty(Environment.CONNECTION_PROVIDER, getConnectionProviderClass().getName());
+ cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, getTransactionManagerLookupClass().getName());
+ cfg.setProperty(Environment.TRANSACTION_STRATEGY, getTransactionFactoryClass().getName());
+ cfg.setProperty(Environment.CACHE_REGION_FACTORY, getCacheRegionFactory().getName());
+ cfg.setProperty(Environment.USE_QUERY_CACHE, String.valueOf(getUseQueryCache()));
+ }
+
+ /**
+ * Settings impl that delegates most calls to the DualNodeTestCase itself, but overrides the
+ * configure method to allow separate cache settings for the second node.
+ */
+ public class SecondNodeSettings implements ExecutionEnvironment.Settings {
+ private final DualNodeTestCase delegate;
+
+ public SecondNodeSettings() {
+ this.delegate = DualNodeTestCase.this;
+ }
+
+ /**
+ * This is the important one -- we extend the delegate's work by adding second-node specific
+ * settings
+ */
+ public void configure(Configuration arg0) {
+ delegate.standardConfigure(arg0);
+ configureSecondNode(arg0);
+ }
+
+ /**
+ * Disable creating of schemas; we let the primary session factory do that to our shared
+ * database.
+ */
+ public boolean createSchema() {
+ return false;
+ }
+
+ /**
+ * Disable creating of schemas; we let the primary session factory do that to our shared
+ * database.
+ */
+ public boolean recreateSchemaAfterFailure() {
+ return false;
+ }
+
+ public void afterConfigurationBuilt(Mappings arg0, Dialect arg1) {
+ delegate.afterConfigurationBuilt(arg0, arg1);
+ }
+
+ public void afterSessionFactoryBuilt(SessionFactoryImplementor arg0) {
+ delegate.afterSessionFactoryBuilt(arg0);
+ }
+
+ public boolean appliesTo(Dialect arg0) {
+ return delegate.appliesTo(arg0);
+ }
+
+ public String getBaseForMappings() {
+ return delegate.getBaseForMappings();
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return delegate.getCacheConcurrencyStrategy();
+ }
+
+ public String[] getMappings() {
+ return delegate.getMappings();
+ }
+
+ public boolean overrideCacheStrategy() {
+ return delegate.overrideCacheStrategy();
+ }
+ }
+
+}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTransactionManagerLookup.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTransactionManagerLookup.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/DualNodeTransactionManagerLookup.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -39,9 +39,9 @@
public class DualNodeTransactionManagerLookup implements TransactionManagerLookup {
public TransactionManager getTransactionManager(Properties props) throws HibernateException {
- String nodeId = props.getProperty(AbstractDualNodeTestCase.NODE_ID_PROP);
+ String nodeId = props.getProperty(DualNodeTestCase.NODE_ID_PROP);
if (nodeId == null)
- throw new HibernateException(AbstractDualNodeTestCase.NODE_ID_PROP + " not configured");
+ throw new HibernateException(DualNodeTestCase.NODE_ID_PROP + " not configured");
return DualNodeJtaTransactionManagerImpl.getInstance(nodeId);
}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/EntityCollectionInvalidationTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -39,8 +39,8 @@
import org.infinispan.notifications.cachelistener.annotation.CacheEntryVisited;
import org.infinispan.notifications.cachelistener.event.CacheEntryVisitedEvent;
import org.jboss.util.collection.ConcurrentSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* EntityCollectionInvalidationTestCase.
@@ -48,8 +48,8 @@
* @author Galder Zamarreño
* @since 3.5
*/
-public class EntityCollectionInvalidationTestCase extends AbstractDualNodeTestCase {
- private static final Logger log = LoggerFactory.getLogger(EntityCollectionInvalidationTestCase.class);
+public class EntityCollectionInvalidationTestCase extends DualNodeTestCase {
+ private static final Log log = LogFactory.getLog(EntityCollectionInvalidationTestCase.class);
private static final long SLEEP_TIME = 50l;
private static final Integer CUSTOMER_ID = new Integer(1);
static int test = 0;
@@ -67,7 +67,7 @@
// Bind a listener to the "local" cache
// Our region factory makes its CacheManager available to us
- CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.LOCAL);
+ CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.LOCAL);
// Cache localCache = localManager.getCache("entity");
Cache localCustomerCache = localManager.getCache(Customer.class.getName());
Cache localContactCache = localManager.getCache(Contact.class.getName());
@@ -76,10 +76,10 @@
localCustomerCache.addListener(localListener);
localContactCache.addListener(localListener);
localCollectionCache.addListener(localListener);
- TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.LOCAL);
+ TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.LOCAL);
// Bind a listener to the "remote" cache
- CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.REMOTE);
+ CacheManager remoteManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.REMOTE);
Cache remoteCustomerCache = remoteManager.getCache(Customer.class.getName());
Cache remoteContactCache = remoteManager.getCache(Contact.class.getName());
Cache remoteCollectionCache = remoteManager.getCache(Customer.class.getName() + ".contacts");
@@ -87,7 +87,7 @@
remoteCustomerCache.addListener(remoteListener);
remoteContactCache.addListener(remoteListener);
remoteCollectionCache.addListener(remoteListener);
- TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.REMOTE);
+ TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.REMOTE);
SessionFactory localFactory = getEnvironment().getSessionFactory();
SessionFactory remoteFactory = getSecondNodeEnvironment().getSessionFactory();
@@ -319,7 +319,7 @@
@Listener
public static class MyListener {
- private static final Logger log = LoggerFactory.getLogger(MyListener.class);
+ private static final Log log = LogFactory.getLog(MyListener.class);
private Set<String> visited = new ConcurrentSet<String>();
private final String name;
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/SessionRefreshTestCase.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/SessionRefreshTestCase.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/functional/cluster/SessionRefreshTestCase.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -41,7 +41,7 @@
* @author Galder Zamarreño
* @since 3.5
*/
-public class SessionRefreshTestCase extends AbstractDualNodeTestCase {
+public class SessionRefreshTestCase extends DualNodeTestCase {
public static final String OUR_PACKAGE = SessionRefreshTestCase.class.getPackage().getName();
@@ -90,41 +90,41 @@
public void testRefreshAfterExternalChange() throws Exception {
// First session factory uses a cache
- CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(AbstractDualNodeTestCase.LOCAL);
+ CacheManager localManager = ClusterAwareRegionFactory.getCacheManager(DualNodeTestCase.LOCAL);
localCache = localManager.getCache(Account.class.getName());
- TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.LOCAL);
+ TransactionManager localTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.LOCAL);
SessionFactory localFactory = getEnvironment().getSessionFactory();
// Second session factory doesn't; just needs a transaction manager
- TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(AbstractDualNodeTestCase.REMOTE);
+ TransactionManager remoteTM = DualNodeJtaTransactionManagerImpl.getInstance(DualNodeTestCase.REMOTE);
SessionFactory remoteFactory = getSecondNodeEnvironment().getSessionFactory();
ClassLoaderTestDAO dao0 = new ClassLoaderTestDAO(localFactory, localTM);
ClassLoaderTestDAO dao1 = new ClassLoaderTestDAO(remoteFactory, remoteTM);
Integer id = new Integer(1);
- dao0.createAccount(dao0.getSmith(), id, new Integer(5), AbstractDualNodeTestCase.LOCAL);
+ dao0.createAccount(dao0.getSmith(), id, new Integer(5), DualNodeTestCase.LOCAL);
// Basic sanity check
Account acct1 = dao1.getAccount(id);
assertNotNull(acct1);
- assertEquals(AbstractDualNodeTestCase.LOCAL, acct1.getBranch());
+ assertEquals(DualNodeTestCase.LOCAL, acct1.getBranch());
// This dao's session factory isn't caching, so cache won't see this change
- dao1.updateAccountBranch(id, AbstractDualNodeTestCase.REMOTE);
+ dao1.updateAccountBranch(id, DualNodeTestCase.REMOTE);
// dao1's session doesn't touch the cache,
// so reading from dao0 should show a stale value from the cache
// (we check to confirm the cache is used)
Account acct0 = dao0.getAccount(id);
assertNotNull(acct0);
- assertEquals(AbstractDualNodeTestCase.LOCAL, acct0.getBranch());
+ assertEquals(DualNodeTestCase.LOCAL, acct0.getBranch());
log.debug("Contents when re-reading from local: " + TestingUtil.printCache(localCache));
// Now call session.refresh and confirm we get the correct value
acct0 = dao0.getAccountWithRefresh(id);
assertNotNull(acct0);
- assertEquals(AbstractDualNodeTestCase.REMOTE, acct0.getBranch());
+ assertEquals(DualNodeTestCase.REMOTE, acct0.getBranch());
log.debug("Contents after refreshing in remote: " + TestingUtil.printCache(localCache));
// Double check with a brand new session, in case the other session
@@ -132,7 +132,7 @@
ClassLoaderTestDAO dao0A = new ClassLoaderTestDAO(localFactory, localTM);
Account acct0A = dao0A.getAccount(id);
assertNotNull(acct0A);
- assertEquals(AbstractDualNodeTestCase.REMOTE, acct0A.getBranch());
+ assertEquals(DualNodeTestCase.REMOTE, acct0A.getBranch());
log.debug("Contents after creating a new session: " + TestingUtil.printCache(localCache));
}
}
Modified: core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionImpl.java
===================================================================
--- core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionImpl.java 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/java/org/hibernate/test/cache/infinispan/tm/XaTransactionImpl.java 2009-11-18 16:56:13 UTC (rev 18005)
@@ -40,8 +40,8 @@
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
/**
* XaResourceCapableTransactionImpl.
@@ -50,7 +50,7 @@
* @since 3.5
*/
public class XaTransactionImpl implements Transaction {
- private static final Logger log = LoggerFactory.getLogger(XaTransactionImpl.class);
+ private static final Log log = LogFactory.getLog(XaTransactionImpl.class);
private int status;
private LinkedList synchronizations;
private Connection connection; // the only resource we care about is jdbc connection
Modified: core/trunk/cache-infinispan/src/test/resources/hibernate.properties
===================================================================
--- core/trunk/cache-infinispan/src/test/resources/hibernate.properties 2009-11-18 16:35:28 UTC (rev 18004)
+++ core/trunk/cache-infinispan/src/test/resources/hibernate.properties 2009-11-18 16:56:13 UTC (rev 18005)
@@ -34,7 +34,3 @@
hibernate.max_fetch_depth 5
hibernate.generate_statistics true
-
-hibernate.cache.use_second_level_cache true
-hibernate.cache.use_query_cache true
-hibernate.cache.region.factory_class org.hibernate.cache.infinispan.InfinispanRegionFactory
\ No newline at end of file
15 years