SVN layout migration for core/branches/Branch_3_2

git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@11766 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2007-06-29 19:51:56 +00:00
parent c654277e62
commit dadc8d3b9b
1053 changed files with 86980 additions and 0 deletions

View File

@ -0,0 +1,34 @@
package org.hibernate.junit;
/**
* A specialized TestCase for running tests in an isolated class-loader
*
* @author Steve Ebersole
*/
public abstract class AbstractClassLoaderIsolatedTestCase extends UnitTestCase {
private ClassLoader parentLoader;
private ClassLoader isolatedLoader;
public AbstractClassLoaderIsolatedTestCase(String string) {
super( string );
}
protected void setUp() throws Exception {
parentLoader = Thread.currentThread().getContextClassLoader();
isolatedLoader = buildIsolatedClassLoader( parentLoader );
Thread.currentThread().setContextClassLoader( isolatedLoader );
super.setUp();
}
protected void tearDown() throws Exception {
super.tearDown();
Thread.currentThread().setContextClassLoader( parentLoader );
releaseIsolatedClassLoader( isolatedLoader );
parentLoader = null;
isolatedLoader = null;
}
protected abstract ClassLoader buildIsolatedClassLoader(ClassLoader parent);
protected abstract void releaseIsolatedClassLoader(ClassLoader isolatedLoader);
}

View File

@ -0,0 +1,50 @@
package org.hibernate.junit;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import junit.framework.TestSuite;
import junit.framework.Test;
import junit.framework.TestCase;
import org.hibernate.test.AllTests;
/**
* A simple class to collect the names of "failure expected" tests...
*
* @author Steve Ebersole
*/
public class FailureExpectedCollector {
public static void main(String[] args) {
Set testNames = collectAllFailureExpectedTestNames();
Iterator itr = testNames.iterator();
int i = 0;
while ( itr.hasNext() ) {
i++;
System.out.println( i + ") " + itr.next() );
}
}
public static Set collectAllFailureExpectedTestNames() {
Set names = new HashSet();
collectFailureExpectedTestNames( names, ( TestSuite ) AllTests.unfilteredSuite() );
return names;
}
public static void collectFailureExpectedTestNames(final Set names, TestSuite suite) {
TestSuiteVisitor.Handler handler = new TestSuiteVisitor.Handler() {
public void handleTestCase(Test test) {
TestCase testCase = ( TestCase ) test;
if ( testCase.getName().endsWith( "FailureExpected" ) ) {
names.add( testCase.getClass().getName() + "#" + testCase.getName() );
}
}
public void startingTestSuite(TestSuite suite) {}
public void completedTestSuite(TestSuite suite) {}
};
TestSuiteVisitor visitor = new TestSuiteVisitor( handler );
visitor.visit( suite );
}
}

View File

@ -0,0 +1,13 @@
package org.hibernate.junit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Well-known-location lookup for the test-skip log...
*
* @author Steve Ebersole
*/
public class SkipLog {
public static final Log LOG = LogFactory.getLog( "org.hibernate.test.SKIPPED" );
}

View File

@ -0,0 +1,42 @@
package org.hibernate.junit;
import java.util.Enumeration;
import junit.framework.TestSuite;
import junit.framework.Test;
/**
* Handles walking a TestSuite hierarchy for recognition of individual tests.
*
* @author Steve Ebersole
*/
public class TestSuiteVisitor {
private final TestSuiteVisitor.Handler handler;
public TestSuiteVisitor(TestSuiteVisitor.Handler handler) {
this.handler = handler;
}
public void visit(TestSuite testSuite) {
handler.startingTestSuite( testSuite );
Enumeration tests = testSuite.tests();
while ( tests.hasMoreElements() ) {
Test test = ( Test ) tests.nextElement();
if ( test instanceof TestSuite ) {
visit( ( TestSuite ) test );
}
else {
handler.handleTestCase( test );
}
}
handler.completedTestSuite( testSuite );
}
public static interface Handler {
public void handleTestCase(Test test);
public void startingTestSuite(TestSuite suite);
public void completedTestSuite(TestSuite suite);
}
}

View File

@ -0,0 +1,84 @@
package org.hibernate.junit;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import junit.framework.AssertionFailedError;
/**
* A basic JUnit {@link junit.framework.TestCase} subclass for
* adding some Hibernate specific behavior and functionality.
*
* @author Steve Ebersole
*/
public abstract class UnitTestCase extends junit.framework.TestCase {
private static final Log log = LogFactory.getLog( UnitTestCase.class );
public UnitTestCase(String string) {
super( string );
}
/**
* runBare overridden in order to apply FailureExpected validations
* as well as start/complete logging
*
* @throws Throwable
*/
public void runBare() throws Throwable {
final boolean doValidate = getName().endsWith( "FailureExpected" ) && Boolean.getBoolean( "hibernate.test.validatefailureexpected" );
try {
log.info( "Starting test [" + fullTestName() + "]" );
super.runBare();
if ( doValidate ) {
fail( "Test marked as FailureExpected, but did not fail!" );
}
}
catch( Throwable t ) {
if ( doValidate ) {
skipExpectedFailure( t );
}
else {
throw t;
}
}
finally {
log.info( "Completed test [" + fullTestName() + "]" );
}
}
protected void skipExpectedFailure(Throwable error) {
reportSkip( "ignoring *FailuredExpected methods", "Failed with: " + error.toString() );
}
// additional assertions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public static void assertElementTypeAssignability(java.util.Collection collection, Class clazz) throws AssertionFailedError {
Iterator itr = collection.iterator();
while ( itr.hasNext() ) {
assertClassAssignability( itr.next().getClass(), clazz );
}
}
public static void assertClassAssignability(Class source, Class target) throws AssertionFailedError {
if ( !target.isAssignableFrom( source ) ) {
throw new AssertionFailedError(
"Classes were not assignment-compatible : source<" + source.getName() +
"> target<" + target.getName() + ">"
);
}
}
// test skipping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public String fullTestName() {
return this.getClass().getName() + "#" + this.getName();
}
protected void reportSkip(String reason, String testDescription) {
SkipLog.LOG.warn( "*** skipping [" + fullTestName() + "] - " + testDescription + " : " + reason, new Exception() );
}
}

View File

@ -0,0 +1,27 @@
package org.hibernate.junit.functional;
import org.hibernate.junit.SkipLog;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public abstract class DatabaseSpecificFunctionalTestCase extends FunctionalTestCase {
public DatabaseSpecificFunctionalTestCase(String string) {
super( string );
}
protected void runTest() throws Throwable {
// Note: this protection comes into play when running
// tests individually. The suite as a whole is already
// "protected" by the fact that these tests are actually
// filtered out of the suite
if ( appliesTo( getDialect() ) ) {
super.runTest();
}
else {
SkipLog.LOG.warn( "skipping database-specific test [" + fullTestName() + "] for dialect [" + getDialect().getClass().getName() + "]" );
}
}
}

View File

@ -0,0 +1,161 @@
package org.hibernate.junit.functional;
import java.util.Iterator;
import java.sql.Blob;
import java.sql.Clob;
import org.hibernate.dialect.Dialect;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Mappings;
import org.hibernate.SessionFactory;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Collection;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class ExecutionEnvironment {
public static final Dialect DIALECT = Dialect.getDialect();
private final ExecutionEnvironment.Settings settings;
private Configuration configuration;
private SessionFactory sessionFactory;
private boolean allowRebuild;
public ExecutionEnvironment(ExecutionEnvironment.Settings settings) {
this.settings = settings;
}
public boolean isAllowRebuild() {
return allowRebuild;
}
public void setAllowRebuild(boolean allowRebuild) {
this.allowRebuild = allowRebuild;
}
public Dialect getDialect() {
return DIALECT;
}
public Configuration getConfiguration() {
return configuration;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void initialize() {
if ( sessionFactory != null ) {
throw new IllegalStateException( "attempt to initialize already initialized ExecutionEnvironment" );
}
if ( ! settings.appliesTo( getDialect() ) ) {
return;
}
Configuration configuration = new Configuration();
configuration.setProperty( Environment.CACHE_PROVIDER, "org.hibernate.cache.HashtableCacheProvider" );
settings.configure( configuration );
applyMappings( configuration );
applyCacheSettings( configuration );
if ( settings.createSchema() ) {
configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
}
// make sure we use the same dialect...
configuration.setProperty( Environment.DIALECT, getDialect().getClass().getName() );
configuration.buildMappings();
settings.afterConfigurationBuilt( configuration.createMappings(), getDialect() );
SessionFactory sessionFactory = configuration.buildSessionFactory();
this.configuration = configuration;
this.sessionFactory = sessionFactory;
settings.afterSessionFactoryBuilt( ( SessionFactoryImplementor ) sessionFactory );
}
private void applyMappings(Configuration configuration) {
String[] mappings = settings.getMappings();
for ( int i = 0; i < mappings.length; i++ ) {
configuration.addResource( settings.getBaseForMappings() + mappings[i], ExecutionEnvironment.class.getClassLoader() );
}
}
private void applyCacheSettings(Configuration configuration) {
if ( settings.getCacheConcurrencyStrategy() != null ) {
Iterator iter = configuration.getClassMappings();
while ( iter.hasNext() ) {
PersistentClass clazz = (PersistentClass) iter.next();
Iterator props = clazz.getPropertyClosureIterator();
boolean hasLob = false;
while ( props.hasNext() ) {
Property prop = (Property) props.next();
if ( prop.getValue().isSimpleValue() ) {
String type = ( ( SimpleValue ) prop.getValue() ).getTypeName();
if ( "blob".equals(type) || "clob".equals(type) ) {
hasLob = true;
}
if ( Blob.class.getName().equals(type) || Clob.class.getName().equals(type) ) {
hasLob = true;
}
}
}
if ( !hasLob && !clazz.isInherited() && settings.overrideCacheStrategy() ) {
configuration.setCacheConcurrencyStrategy( clazz.getEntityName(), settings.getCacheConcurrencyStrategy() );
}
}
iter = configuration.getCollectionMappings();
while ( iter.hasNext() ) {
Collection coll = (Collection) iter.next();
configuration.setCollectionCacheConcurrencyStrategy( coll.getRole(), settings.getCacheConcurrencyStrategy() );
}
}
}
public void rebuild() {
if ( !allowRebuild ) {
return;
}
if ( sessionFactory != null ) {
sessionFactory.close();
sessionFactory = null;
}
sessionFactory = configuration.buildSessionFactory();
settings.afterSessionFactoryBuilt( ( SessionFactoryImplementor ) sessionFactory );
}
public void complete() {
if ( sessionFactory != null ) {
sessionFactory.close();
sessionFactory = null;
}
configuration = null;
}
public static interface Settings {
public String[] getMappings();
public String getBaseForMappings();
public boolean createSchema();
public boolean recreateSchemaAfterFailure();
public void configure(Configuration cfg);
public boolean overrideCacheStrategy();
public String getCacheConcurrencyStrategy();
public void afterSessionFactoryBuilt(SessionFactoryImplementor sfi);
public void afterConfigurationBuilt(Mappings mappings, Dialect dialect);
public boolean appliesTo(Dialect dialect);
}
}

View File

@ -0,0 +1,505 @@
package org.hibernate.junit.functional;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Mappings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.SessionFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.engine.SessionFactoryImplementor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Most of the Hibernate test suite in fact is a series of functional tests, not
* unit tests. Here is a base class for these functional tests.
*
* @author Steve Ebersole
*/
public abstract class FunctionalTestCase extends UnitTestCase implements ExecutionEnvironment.Settings {
private static final Log log = LogFactory.getLog( FunctionalTestCase.class );
private ExecutionEnvironment environment;
private boolean isEnvironmentLocallyManaged;
private org.hibernate.classic.Session session;
public FunctionalTestCase(String string) {
super( string );
}
public ExecutionEnvironment getEnvironment() {
return environment;
}
public void setEnvironment(ExecutionEnvironment environment) {
this.environment = environment;
}
protected void prepareTest() throws Exception {
}
protected void cleanupTest() throws Exception {
}
// JUnit hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Override {@link junit.framework.TestCase#setUp()} to check if we need
* to build a locally managed execution environment.
*
* @throws Exception
*/
protected final void setUp() throws Exception {
if ( environment == null ) {
log.info( "Building locally managed execution env" );
isEnvironmentLocallyManaged = true;
environment = new ExecutionEnvironment( this );
environment.initialize();
}
prepareTest();
}
/**
* Override {@link junit.framework.TestCase#tearDown()} to tear down
* the execution environment if it is locally managed.
*
* @throws Exception
*/
protected final void tearDown() throws Exception {
cleanupTest();
if ( isEnvironmentLocallyManaged ) {
log.info( "Destroying locally managed execution env" );
environment.complete();
environment = null;
}
}
/**
* runTest is overridden in order to apply session closure assertions.
*
* @throws Throwable
*/
protected void runTest() throws Throwable {
final boolean stats = sfi().getStatistics().isStatisticsEnabled();
try {
if ( stats ) {
sfi().getStatistics().clear();
}
super.runTest();
if ( stats ) {
sfi().getStatistics().logSummary();
}
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
session = null;
fail( "unclosed session" );
}
else {
session = null;
}
assertAllDataRemoved();
}
catch ( Throwable e ) {
log.trace( "test run resulted in error; attempting to cleanup", e );
try {
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
}
}
catch ( Exception ignore ) {
}
try {
if ( recreateSchemaAfterFailure() && environment != null ) {
environment.rebuild();
}
}
catch ( Exception ignore ) {
}
throw e;
}
}
protected void assertAllDataRemoved() {
if ( !createSchema() ) {
return; // no tables were created...
}
if ( !Boolean.getBoolean( "hibernate.test.validateDataCleanup" ) ) {
return;
}
Session tmpSession = getSessions().openSession();
try {
List list = tmpSession.createQuery( "select o from java.lang.Object o" ).list();
Map items = new HashMap();
if ( !list.isEmpty() ) {
for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
Integer l = ( Integer ) items.get( tmpSession.getEntityName( element ) );
if ( l == null ) {
l = new Integer( 0 );
}
l = new Integer( l.intValue() + 1 );
items.put( tmpSession.getEntityName( element ), l );
System.out.println( "Data left: " + element );
}
fail( "Data is left in the database: " + items.toString() );
}
}
finally {
try {
tmpSession.close();
}
catch( Throwable t ) {
// intentionally empty
}
}
}
protected void skipExpectedFailure(Throwable error) {
super.skipExpectedFailure( error );
try {
if ( recreateSchemaAfterFailure() && environment != null ) {
environment.rebuild();
}
}
catch ( Exception ignore ) {
}
}
// ExecutionEnvironment.Settings implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~
public String getBaseForMappings() {
return "org/hibernate/test/";
}
public boolean createSchema() {
return true;
}
public boolean recreateSchemaAfterFailure() {
return true;
}
public void configure(Configuration cfg) {
}
public boolean overrideCacheStrategy() {
return true;
}
public String getCacheConcurrencyStrategy() {
return "nonstrict-read-write";
}
public void afterSessionFactoryBuilt(SessionFactoryImplementor sfi) {
}
public void afterConfigurationBuilt(Mappings mappings, Dialect dialect) {
}
/**
* Intended to indicate that this test class as a whole is intended for
* a dialect or series of dialects. Skips here (appliesTo = false) therefore
* simply indicate that the given tests target a particular feature of the
* checked database and none of the tests on this class should be run for the
* checked dialect.
*
* @param dialect The dialect to be checked.
* @return False if the test class as a whole is specifically targetting
* a dialect (or series of dialects) other than the indicated dialect
* and the test should therefore be skipped in its entirety;
* true otherwise.
*/
public boolean appliesTo(Dialect dialect) {
return true;
}
// methods for subclasses to access environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the factory for this test environment.
*
* @return The factory.
*/
protected SessionFactory getSessions() {
return environment.getSessionFactory();
}
/**
* Get the factory for this test environment, casted to {@link org.hibernate.engine.SessionFactoryImplementor}.
* <p/>
* Shorthand for ( {@link org.hibernate.engine.SessionFactoryImplementor} ) {@link #getSessions()}...
*
* @return The factory
*/
protected SessionFactoryImplementor sfi() {
return ( SessionFactoryImplementor ) getSessions();
}
protected Dialect getDialect() {
return ExecutionEnvironment.DIALECT;
}
protected Configuration getCfg() {
return environment.getConfiguration();
}
public org.hibernate.classic.Session openSession() throws HibernateException {
session = getSessions().openSession();
return session;
}
public org.hibernate.classic.Session openSession(Interceptor interceptor) throws HibernateException {
session = getSessions().openSession(interceptor);
return session;
}
/**
* Is connection at least read committed?
* <p/>
* Not, that this skip check relies on the JDBC driver reporting
* the true isolation level correctly. HSQLDB, for example, will
* report whatever you specify as the isolation
* (Connection.setTransationIsolation()), even though it only supports
* read-uncommitted.
*
* @param scenario text description of the scenario being tested.
* @return true if read-committed isolation is maintained.
*/
protected boolean readCommittedIsolationMaintained(String scenario) {
int isolation = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
Session testSession = null;
try {
testSession = openSession();
isolation = testSession.connection().getTransactionIsolation();
}
catch( Throwable ignore ) {
}
finally {
if ( testSession != null ) {
try {
testSession.close();
}
catch( Throwable ignore ) {
}
}
}
if ( isolation < java.sql.Connection.TRANSACTION_READ_COMMITTED ) {
reportSkip( "environment does not support at least read committed isolation", scenario );
return false;
}
else {
return true;
}
}
/**
* Does the db/dialect support using a column's physical name in the order-by clause
* even after it has been aliased in the select clause. This is not actually
* required by the SQL spec, although virtually ever DB in the world supports this
* (the most glaring omission here being IBM-variant DBs ala DB2 and Derby).
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean allowsPhysicalColumnNameInOrderby(String testDescription) {
if ( DB2Dialect.class.isInstance( getDialect() ) ) {
// https://issues.apache.org/jira/browse/DERBY-1624
reportSkip( "Dialect does not support physical column name in order-by clause after it is aliased", testDescription );
return false;
}
return true;
}
/**
* Does the db/dialect support using a column's physical name in the having clause
* even after it has been aliased in the select/group-by clause. This is not actually
* required by the SQL spec, although virtually ever DB in the world supports this.
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean allowsPhysicalColumnNameInHaving(String testDescription) {
// I only *know* of this being a limitation on Derby, although I highly suspect
// it is a limitation on any IBM/DB2 variant
if ( DerbyDialect.class.isInstance( getDialect() ) ) {
// https://issues.apache.org/jira/browse/DERBY-1624
reportSkip( "Dialect does not support physical column name in having clause after it is aliased", testDescription );
return false;
}
return true;
}
/**
* Does the db/dialect support empty lists in the IN operator?
* <p/>
* For example, is "... a.b IN () ..." supported?
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean dialectSupportsEmptyInList(String testDescription) {
if ( ! getDialect().supportsEmptyInList() ) {
reportSkip( "Dialect does not support SQL empty in list : x in ()", testDescription );
return false;
}
return true;
}
/**
* Is the db/dialect sensitive in terms of string comparisons?
* @param testDescription description of the scenario being tested.
* @return true if sensitive
*/
protected boolean dialectIsCaseSensitive(String testDescription) {
if ( ! getDialect().areStringComparisonsCaseInsensitive() ) {
reportSkip( "Dialect is case sensitive. ", testDescription );
return true;
}
return false;
}
protected boolean supportsRowValueConstructorSyntaxInInList() {
if ( ! getDialect().supportsRowValueConstructorSyntaxInInList() ) {
reportSkip( "Dialect does not support 'tuple' syntax as part of an IN value list", "query support" );
return false;
}
return true;
}
protected boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
if ( ! getDialect().supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() ) {
reportSkip( "Driver does not support 'position query' methods on forward-only cursors", "query support" );
return false;
}
return true;
}
protected boolean supportsCircularCascadeDelete() {
if ( ! getDialect().supportsCircularCascadeDeleteConstraints() ) {
reportSkip( "db/dialect does not support 'circular' cascade delete constraints", "cascade delete constraint support" );
return false;
}
return true;
}
protected boolean supportsSubselectOnLeftSideIn() {
if ( ! getDialect().supportsSubselectAsInPredicateLHS() ) {
reportSkip( "Database does not support (<subselect>) in ( ... ) ", "query support" );
return false;
}
return true;
}
/**
* Expected LOB usage pattern is such that I can perform an insert
* via prepared statement with a parameter binding for a LOB value
* without crazy casting to JDBC driver implementation-specific classes...
* <p/>
* Part of the trickiness here is the fact that this is largely
* driver dependent. For Oracle, which is notoriously bad with
* LOB support in their drivers actually does a pretty good job with
* LOB support as of the 10.2.x versions of their drivers...
*
* @return True if expected usage pattern is support; false otherwise.
*/
protected boolean supportsExpectedLobUsagePattern() {
if ( ! getDialect().supportsExpectedLobUsagePattern() ) {
reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
return false;
}
return true;
}
/**
* Does the current dialect support propogating changes to LOB
* values back to the database? Talking about mutating the
* underlying value as opposed to supplying a new
* LOB instance...
*
* @return True if the changes are propogated back to the
* database; false otherwise.
*/
protected boolean supportsLobValueChangePropogation() {
if ( ! getDialect().supportsLobValueChangePropogation() ) {
reportSkip( "database/driver does not support propogating LOB value change back to database", "LOB support" );
return false;
}
return true;
}
/**
* Is it supported to materialize a LOB locator outside the transaction in
* which it was created?
* <p/>
* Again, part of the trickiness here is the fact that this is largely
* driver dependent.
* <p/>
* NOTE: all database I have tested which {@link #supportsExpectedLobUsagePattern()}
* also support the ability to materialize a LOB outside the owning transaction...
*
* @return True if unbounded materialization is supported; false otherwise.
*/
protected boolean supportsUnboundedLobLocatorMaterialization() {
if ( !getDialect().supportsUnboundedLobLocatorMaterialization() ) {
reportSkip( "database/driver does not support materializing a LOB locator outside the 'owning' transaction", "LOB support" );
return false;
}
return true;
}
protected boolean supportsSubqueryOnMutatingTable() {
if ( !getDialect().supportsSubqueryOnMutatingTable() ) {
reportSkip( "database/driver does not support referencing mutating table in subquery", "bulk DML support" );
return false;
}
return true;
}
protected boolean dialectIs(Class dialectClass) {
return dialectClass.isInstance( getDialect() );
}
protected boolean dialectIsOneOf(Class[] dialectClasses) {
for ( int i = 0; i < dialectClasses.length; i++ ) {
if ( dialectClasses[i].isInstance( getDialect() ) ) {
return true;
}
}
return false;
}
protected boolean dialectIsNot(Class dialectClass) {
return ! dialectIs( dialectClass );
}
protected boolean dialectIsNot(Class[] dialectClasses) {
return ! dialectIsOneOf( dialectClasses );
}
}

View File

@ -0,0 +1,129 @@
package org.hibernate.junit.functional;
import junit.framework.TestSuite;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A specialized {@link junit.framework.TestSuite} implementation intended
* for use as an aggregate for a single test class specifically for the purpose
* of maintaing a single {@link org.hibernate.SessionFactory} for executings all
* tests defined as part of the given functional test class.
*
* @author Steve Ebersole
*/
public class FunctionalTestClassTestSuite extends TestSuite {
private static final Log log = LogFactory.getLog( FunctionalTestClassTestSuite.class );
private ExecutionEnvironment.Settings settings;
private ExecutionEnvironment environment;
private Throwable environmentSetupError;
private int testCount;
private int testPosition;
public FunctionalTestClassTestSuite(Class testClass, String name) {
super( testClass, name );
}
public FunctionalTestClassTestSuite(Class testClass) {
this( testClass, testClass.getName() );
}
/**
* Constructor form used during {@link org.hibernate.test.AllTests} filtering...
*
* @param name The name.
*/
private FunctionalTestClassTestSuite(String name) {
super( name );
}
public void addTest(Test test) {
log.trace( "adding test [" + test + "]" );
if ( settings == null ) {
if ( test instanceof ExecutionEnvironment.Settings ) {
settings = ( ExecutionEnvironment.Settings ) test;
// todo : we could also centralize the skipping of "database specific" tests here
// instead of duplicating this notion in AllTests and DatabaseSpecificFunctionalTestCase.
// as a test gets added, simply check to see if we should really add it via
// DatabaseSpecificFunctionalTestCase.appliesTo( ExecutionEnvironment.DIALECT )...
}
}
testCount++;
super.addTest( test );
}
public void run(TestResult testResult) {
if ( testCount == 0 ) {
// might be zero if database-specific...
return;
}
try {
log.info( "Starting test-suite [" + getName() + "]" );
setUp();
testPosition = 0;
super.run( testResult );
}
finally {
try {
tearDown();
}
catch( Throwable ignore ) {
}
log.info( "Completed test-suite [" + getName() + "]" );
}
}
public void runTest(Test test, TestResult testResult) {
testPosition++;
if ( environmentSetupError != null ) {
testResult.startTest( test );
testResult.addError( test, environmentSetupError );
testResult.endTest( test );
return;
}
if ( ! ( test instanceof FunctionalTestCase ) ) {
super.runTest( test, testResult );
}
else {
FunctionalTestCase functionalTest = ( ( FunctionalTestCase ) test );
try {
// disallow rebuilding the schema because this is the last test
// in this suite, thus it is about to get dropped immediately
// afterwards anyway...
environment.setAllowRebuild( testPosition < testCount );
functionalTest.setEnvironment( environment );
super.runTest( functionalTest, testResult );
}
finally {
functionalTest.setEnvironment( null );
}
}
}
protected void setUp() {
if ( settings == null ) {
return;
}
log.info( "Building aggregated execution environment" );
try {
environment = new ExecutionEnvironment( settings );
environment.initialize();
}
catch( Throwable t ) {
environmentSetupError = t;
}
}
protected void tearDown() {
if ( environment != null ) {
log.info( "Destroying aggregated execution environment" );
environment.complete();
this.environment = null;
}
}
}

View File

@ -0,0 +1,441 @@
//$Id$
package org.hibernate.test;
import java.lang.reflect.Constructor;
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.hibernate.dialect.Dialect;
import org.hibernate.junit.TestSuiteVisitor;
import org.hibernate.test.abstractembeddedcomponents.cid.AbstractCompositeIdTest;
import org.hibernate.test.abstractembeddedcomponents.propertyref.AbstractComponentPropertyRefTest;
import org.hibernate.test.any.AnyTypeTest;
import org.hibernate.test.array.ArrayTest;
import org.hibernate.test.ast.ASTIteratorTest;
import org.hibernate.test.ast.ASTUtilTest;
import org.hibernate.test.batchfetch.BatchFetchTest;
import org.hibernate.test.bidi.AuctionTest;
import org.hibernate.test.bidi.AuctionTest2;
import org.hibernate.test.bytecode.BytecodeSuite;
import org.hibernate.test.cache.CacheSuite;
import org.hibernate.test.cascade.RefreshTest;
import org.hibernate.test.cid.CompositeIdTest;
import org.hibernate.test.collection.CollectionSuite;
import org.hibernate.test.component.ComponentSuite;
import org.hibernate.test.compositeelement.CompositeElementTest;
import org.hibernate.test.connections.ConnectionsSuite;
import org.hibernate.test.criteria.CriteriaQueryTest;
import org.hibernate.test.cuk.CompositePropertyRefTest;
import org.hibernate.test.cut.CompositeUserTypeTest;
import org.hibernate.test.deletetransient.DeleteTransientEntityTest;
import org.hibernate.test.dialect.functional.DialectFunctionalTestsSuite;
import org.hibernate.test.dialect.unit.DialectUnitTestsSuite;
import org.hibernate.test.discriminator.DiscriminatorTest;
import org.hibernate.test.dynamicentity.interceptor.InterceptorDynamicEntityTest;
import org.hibernate.test.dynamicentity.tuplizer.TuplizerDynamicEntityTest;
import org.hibernate.test.ecid.EmbeddedCompositeIdTest;
import org.hibernate.test.entitymode.EntityModeSuite;
import org.hibernate.test.exception.SQLExceptionConversionTest;
import org.hibernate.test.extralazy.ExtraLazyTest;
import org.hibernate.test.filter.DynamicFilterTest;
import org.hibernate.test.formulajoin.FormulaJoinTest;
import org.hibernate.test.generated.GeneratedPropertySuite;
import org.hibernate.test.generatedkeys.GeneratedKeysSuite;
import org.hibernate.test.hql.HQLSuite;
import org.hibernate.test.id.MultipleHiLoPerTableGeneratorTest;
import org.hibernate.test.idbag.IdBagTest;
import org.hibernate.test.idclass.IdClassTest;
import org.hibernate.test.idprops.IdentifierPropertyReferencesTest;
import org.hibernate.test.immutable.ImmutableTest;
import org.hibernate.test.insertordering.InsertOrderingTest;
import org.hibernate.test.instrument.buildtime.InstrumentTest;
import org.hibernate.test.instrument.runtime.CGLIBInstrumentationTest;
import org.hibernate.test.instrument.runtime.JavassistInstrumentationTest;
import org.hibernate.test.interceptor.InterceptorTest;
import org.hibernate.test.interfaceproxy.InterfaceProxyTest;
import org.hibernate.test.iterate.IterateTest;
import org.hibernate.test.join.JoinTest;
import org.hibernate.test.joinedsubclass.JoinedSubclassTest;
import org.hibernate.test.joinfetch.JoinFetchTest;
import org.hibernate.test.jpa.JPAComplianceSuite;
import org.hibernate.test.keymanytoone.KeyManyToOneSuite;
import org.hibernate.test.lazycache.InstrumentCacheTest;
import org.hibernate.test.lazycache.InstrumentCacheTest2;
import org.hibernate.test.lazyonetoone.LazyOneToOneTest;
import org.hibernate.test.legacy.ABCProxyTest;
import org.hibernate.test.legacy.ABCTest;
import org.hibernate.test.legacy.CacheTest;
import org.hibernate.test.legacy.ComponentNotNullTest;
import org.hibernate.test.legacy.ConfigurationPerformanceTest;
import org.hibernate.test.legacy.FooBarTest;
import org.hibernate.test.legacy.FumTest;
import org.hibernate.test.legacy.IJ2Test;
import org.hibernate.test.legacy.IJTest;
import org.hibernate.test.legacy.MapTest;
import org.hibernate.test.legacy.MasterDetailTest;
import org.hibernate.test.legacy.MultiTableTest;
import org.hibernate.test.legacy.NonReflectiveBinderTest;
import org.hibernate.test.legacy.OneToOneCacheTest;
import org.hibernate.test.legacy.ParentChildTest;
import org.hibernate.test.legacy.QueryByExampleTest;
import org.hibernate.test.legacy.SQLFunctionsTest;
import org.hibernate.test.legacy.SQLLoaderTest;
import org.hibernate.test.legacy.StatisticsTest;
import org.hibernate.test.lob.LobSuite;
import org.hibernate.test.manytomany.ManyToManyTest;
import org.hibernate.test.map.MapIndexFormulaTest;
import org.hibernate.test.mapcompelem.MapCompositeElementTest;
import org.hibernate.test.mapelemformula.MapElementFormulaTest;
import org.hibernate.test.mapping.PersistentClassVisitorTest;
import org.hibernate.test.mapping.ValueVisitorTest;
import org.hibernate.test.mappingexception.MappingExceptionTest;
import org.hibernate.test.mixed.MixedTest;
import org.hibernate.test.naturalid.NaturalIdSuite;
import org.hibernate.test.ondelete.OnDeleteTest;
import org.hibernate.test.onetomany.OneToManyTest;
import org.hibernate.test.onetoone.OneToOneSuite;
import org.hibernate.test.ops.OpsSuite;
import org.hibernate.test.optlock.OptimisticLockTest;
import org.hibernate.test.ordered.OrderByTest;
import org.hibernate.test.orphan.OrphanSuite;
import org.hibernate.test.pagination.PaginationTest;
import org.hibernate.test.propertyref.PropertyRefSuite;
import org.hibernate.test.proxy.ProxyTest;
import org.hibernate.test.querycache.QueryCacheTest;
import org.hibernate.test.readonly.ReadOnlyTest;
import org.hibernate.test.reattachment.ReattachmentSuite;
import org.hibernate.test.rowid.RowIdTest;
import org.hibernate.test.sorted.SortTest;
import org.hibernate.test.sql.NativeSqlSupportSuite;
import org.hibernate.test.stats.SessionStatsTest;
import org.hibernate.test.stats.StatsTest;
import org.hibernate.test.subclassfilter.DiscrimSubclassFilterTest;
import org.hibernate.test.subclassfilter.JoinedSubclassFilterTest;
import org.hibernate.test.subclassfilter.UnionSubclassFilterTest;
import org.hibernate.test.subselect.SubselectTest;
import org.hibernate.test.subselectfetch.SubselectFetchTest;
import org.hibernate.test.ternary.TernaryTest;
import org.hibernate.test.timestamp.TimestampTest;
import org.hibernate.test.tm.CMTTest;
import org.hibernate.test.typedmanytoone.TypedManyToOneTest;
import org.hibernate.test.typedonetoone.TypedOneToOneTest;
import org.hibernate.test.typeparameters.TypeParameterTest;
import org.hibernate.test.unconstrained.UnconstrainedTest;
import org.hibernate.test.unidir.BackrefTest;
import org.hibernate.test.unionsubclass.UnionSubclassTest;
import org.hibernate.test.usercollection.UserCollectionTypeSuite;
import org.hibernate.test.util.UtilSuite;
import org.hibernate.test.version.VersionTest;
import org.hibernate.test.version.db.DbVersionTest;
import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest;
import org.hibernate.test.where.WhereTest;
/**
* @author Gavin King
*/
public class AllTests {
/**
* Returns the entire test suite (both legacy and new
*
* @return the entire test suite
*/
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest( NewTests.suite() );
suite.addTest( LegacyTests.suite() );
return suite;
}
/**
* Returns the entire test suite (both legacy and new) w/o filtering
*
* @return the entire test suite
*/
public static Test unfilteredSuite() {
TestSuite suite = new TestSuite();
suite.addTest( NewTests.unfilteredSuite() );
suite.addTest( LegacyTests.unfilteredSuite() );
return suite;
}
/**
* Runs the entire test suite.
* <p/>
* @see #suite
* @param args n/a
*/
public static void main(String args[]) {
TestRunner.run( suite() );
}
/**
* An inner class representing the new test suite.
*/
public static class NewTests {
/**
* Returns the new test suite (filtered)
*
* @return the new test suite
*/
public static Test suite() {
return filter( ( TestSuite ) unfilteredSuite() );
}
/**
* Returns the new test suite (unfiltered)
*
* @return the new test suite
*/
public static Test unfilteredSuite() {
TestSuite suite = new TestSuite("New tests suite");
suite.addTest( OpsSuite.suite() );
suite.addTest( NaturalIdSuite.suite() );
suite.addTest( ComponentSuite.suite() );
suite.addTest( ProxyTest.suite() );
suite.addTest( VersionTest.suite() );
suite.addTest( TimestampTest.suite() );
suite.addTest( InterceptorTest.suite() );
suite.addTest( EmbeddedCompositeIdTest.suite() );
suite.addTest( ImmutableTest.suite() );
suite.addTest( ReadOnlyTest.suite() );
suite.addTest( IdClassTest.suite() );
suite.addTest( ArrayTest.suite() );
suite.addTest( TernaryTest.suite() );
suite.addTest( CollectionSuite.suite() );
suite.addTest( IdBagTest.suite() );
suite.addTest( MapCompositeElementTest.suite() );
suite.addTest( MapIndexFormulaTest.suite() );
suite.addTest( MapElementFormulaTest.suite() );
suite.addTest( BackrefTest.suite() );
suite.addTest( BatchFetchTest.suite() );
suite.addTest( CompositeIdTest.suite() );
suite.addTest( CompositeElementTest.suite() );
suite.addTest( CompositePropertyRefTest.suite() );
suite.addTest( FormulaJoinTest.suite() );
suite.addTest( DiscriminatorTest.suite() );
suite.addTest( EntityModeSuite.suite() );
suite.addTest( DynamicFilterTest.suite() );
suite.addTest( InterfaceProxyTest.suite() );
suite.addTest( OrphanSuite.suite() );
suite.addTest( JoinTest.suite() );
suite.addTest( JoinedSubclassTest.suite() );
suite.addTest( org.hibernate.test.unionsubclass2.UnionSubclassTest.suite() );
suite.addTest( MixedTest.suite() );
suite.addTest( OneToManyTest.suite() );
suite.addTest( ManyToManyTest.suite() );
suite.addTest( OneToOneSuite.suite() );
suite.addTest( OptimisticLockTest.suite() );
suite.addTest( PropertyRefSuite.suite() );
suite.addTest( NativeSqlSupportSuite.suite() );
suite.addTest( CriteriaQueryTest.suite() );
suite.addTest( SubselectTest.suite() );
suite.addTest( SubselectFetchTest.suite() );
suite.addTest( JoinFetchTest.suite() );
suite.addTest( UnionSubclassTest.suite() );
suite.addTest( ASTIteratorTest.suite() );
suite.addTest( HQLSuite.suite() );
suite.addTest( ASTUtilTest.suite() );
suite.addTest( CacheSuite.suite() );
suite.addTest( QueryCacheTest.suite() );
suite.addTest( CompositeUserTypeTest.suite() );
suite.addTest( TypeParameterTest.suite() );
suite.addTest( TypedOneToOneTest.suite() );
suite.addTest( TypedManyToOneTest.suite() );
suite.addTest( CMTTest.suite() );
suite.addTest( MultipleHiLoPerTableGeneratorTest.suite() );
suite.addTest( UnionSubclassFilterTest.suite() );
suite.addTest( JoinedSubclassFilterTest.suite() );
suite.addTest( DiscrimSubclassFilterTest.suite() );
suite.addTest( UnconstrainedTest.suite() );
suite.addTest( RowIdTest.suite() );
suite.addTest( OnDeleteTest.suite() );
suite.addTest( OrderByTest.suite() );
suite.addTest( SortTest.suite() );
suite.addTest( WhereTest.suite() );
suite.addTest( IterateTest.suite() );
suite.addTest( RefreshTest.suite() );
suite.addTest( ExtraLazyTest.suite() );
suite.addTest( StatsTest.suite() );
suite.addTest( SessionStatsTest.suite() );
suite.addTest( ConnectionsSuite.suite() );
suite.addTest( SQLExceptionConversionTest.suite() );
suite.addTest( ValueVisitorTest.suite() );
suite.addTest( PersistentClassVisitorTest.suite() );
suite.addTest( AuctionTest.suite() );
suite.addTest( AuctionTest2.suite() );
suite.addTest( PaginationTest.suite() );
suite.addTest( MappingExceptionTest.suite() );
if ( InstrumentTest.isRunnable() ) {
suite.addTest( InstrumentTest.suite() );
}
if ( LazyOneToOneTest.isRunnable() ) {
suite.addTest( LazyOneToOneTest.suite() );
}
if ( InstrumentCacheTest.isRunnable() ) {
suite.addTest( InstrumentCacheTest.suite() );
}
if ( InstrumentCacheTest2.isRunnable() ) {
suite.addTest( InstrumentCacheTest2.suite() );
}
suite.addTest( CGLIBInstrumentationTest.suite() );
suite.addTest( JavassistInstrumentationTest.suite() );
suite.addTest( SybaseTimestampVersioningTest.suite() );
suite.addTest( DbVersionTest.suite() );
suite.addTest( GeneratedPropertySuite.suite() );
suite.addTest( GeneratedKeysSuite.suite() );
suite.addTest( InterceptorDynamicEntityTest.suite() );
suite.addTest( TuplizerDynamicEntityTest.suite() );
suite.addTest( BytecodeSuite.suite() );
suite.addTest( JPAComplianceSuite.suite() );
suite.addTest( AbstractComponentPropertyRefTest.suite() );
suite.addTest( AbstractCompositeIdTest.suite() );
suite.addTest( UtilSuite.suite() );
suite.addTest( AnyTypeTest.suite() );
suite.addTest( LobSuite.suite() );
suite.addTest( IdentifierPropertyReferencesTest.suite() );
suite.addTest( DeleteTransientEntityTest.suite() );
suite.addTest( UserCollectionTypeSuite.suite() );
suite.addTest( KeyManyToOneSuite.suite() );
suite.addTest( DialectFunctionalTestsSuite.suite() );
suite.addTest( DialectUnitTestsSuite.suite() );
suite.addTest( InsertOrderingTest.suite() );
suite.addTest( ReattachmentSuite.suite() );
return suite;
}
/**
* Runs the new test suite
*
* @param args n/a
*/
public static void main(String[] args) {
TestRunner.run( suite() );
}
}
/**
* An inner class representing the legacy test suite.
*/
public static class LegacyTests {
/**
* Returns the legacy test suite
*
* @return the legacy test suite
*/
public static Test suite() {
return filter( ( TestSuite ) unfilteredSuite() );
}
public static Test unfilteredSuite() {
TestSuite suite = new TestSuite("Legacy tests suite");
suite.addTest( FumTest.suite() );
suite.addTest( MasterDetailTest.suite() );
suite.addTest( ParentChildTest.suite() );
suite.addTest( ABCTest.suite() );
suite.addTest( ABCProxyTest.suite() );
suite.addTest( SQLFunctionsTest.suite() );
suite.addTest( SQLLoaderTest.suite() );
suite.addTest( MultiTableTest.suite() );
suite.addTest( MapTest.suite() );
suite.addTest( QueryByExampleTest.suite() );
suite.addTest( ComponentNotNullTest.suite() );
suite.addTest( IJTest.suite() );
suite.addTest( IJ2Test.suite() );
suite.addTest( FooBarTest.suite() );
suite.addTest( StatisticsTest.suite() );
suite.addTest( CacheTest.suite() );
suite.addTest( OneToOneCacheTest.suite() );
suite.addTest( NonReflectiveBinderTest.suite() );
suite.addTest( ConfigurationPerformanceTest.suite() ); // Added to ensure we can utilize the recommended performance tips ;)
return suite;
}
/**
* Run the legacy test suite
*
* @param args n/a
*/
public static void main(String[] args) {
TestRunner.run( suite() );
}
}
private static TestSuite filter(TestSuite testSuite) {
FilterHandler handler = new FilterHandler();
TestSuiteVisitor visitor = new TestSuiteVisitor( handler );
visitor.visit( testSuite );
return handler.getFilteredTestSuite();
}
private static class TestSuiteStackEntry {
public final TestSuite testSuite;
public final TestSuiteStackEntry parentEntry;
public TestSuiteStackEntry(TestSuite testSuite, TestSuiteStackEntry parentEntry) {
this.testSuite = testSuite;
this.parentEntry = parentEntry;
if ( parentEntry != null ) {
parentEntry.testSuite.addTest( testSuite );
}
}
}
private static class FilterHandler implements TestSuiteVisitor.Handler {
private TestSuiteStackEntry topStackElement;
private TestSuiteStackEntry currentStackElement;
private Dialect dialect = Dialect.getDialect();
public void handleTestCase(Test test) {
if ( test instanceof TestCase ) {
TestCase hibernateTestCase = ( TestCase ) test;
if ( ! hibernateTestCase.appliesTo( dialect ) ) {
System.out.println( "skipping test [" + hibernateTestCase.fullTestName() + "] for dialect [" + dialect.getClass().getName() + "]" );
}
else {
currentStackElement.testSuite.addTest( test );
}
}
else {
currentStackElement.testSuite.addTest( test );
}
}
public void startingTestSuite(TestSuite suite) {
currentStackElement = new TestSuiteStackEntry( instantiateCopy( suite ), currentStackElement );
if ( topStackElement == null ) {
topStackElement = currentStackElement;
}
}
public void completedTestSuite(TestSuite suite) {
if ( currentStackElement != null ) {
currentStackElement = currentStackElement.parentEntry;
}
}
public TestSuite getFilteredTestSuite() {
return topStackElement.testSuite;
}
private static final Class[] EXPECTED_CTOR_SIG = new Class[] { String.class };
private TestSuite instantiateCopy(TestSuite suite) {
try {
Class testSuiteClass = suite.getClass();
Constructor ctor = testSuiteClass.getDeclaredConstructor( EXPECTED_CTOR_SIG );
ctor.setAccessible( true );
return ( TestSuite ) ctor.newInstance( new Object[] { suite.getName() } );
}
catch ( Throwable t ) {
throw new RuntimeException( "Unable to build test suite copy [" + suite + "]", t );
}
}
}
}

View File

@ -0,0 +1,616 @@
//$Id$
package org.hibernate.test;
import java.sql.Blob;
import java.sql.Clob;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import junit.framework.AssertionFailedError;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue;
public abstract class TestCase extends junit.framework.TestCase {
private static SessionFactory sessions;
private static Configuration cfg;
private static Dialect dialect;
private static Class lastTestClass;
private org.hibernate.classic.Session session;
public TestCase(String name) {
super( name );
}
// methods for subclasses to change test environment ~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the mapping resources to be used to build the configuration.
* <p/>
* Resources should be relative to {@link #getBaseForMappings()}
*
* @return The mapping resources
*/
protected abstract String[] getMappings();
/**
* The base name for relative mapping resources. The default is
* <tt>org/hibernate/test/</tt>
*
* @return the mapping resource base
*/
protected String getBaseForMappings() {
return "org/hibernate/test/";
}
/**
* Should the database schema be (re)created
*
* @return True for auto export (including recreation on test failure).
*/
protected boolean recreateSchema() {
return true;
}
protected boolean dropAfterFailure() {
return true;
}
/**
* Apply any test-specific configuration prior to building the factory.
*
* @param cfg The configuration which will be used to construct the factory.
*/
protected void configure(Configuration cfg) {
}
protected boolean overrideCacheStrategy() {
return true;
}
protected String getCacheConcurrencyStrategy() {
return "nonstrict-read-write";
}
// methods for subclasses to access environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the factory for this test environment.
*
* @return The factory.
*/
protected SessionFactory getSessions() {
return sessions;
}
/**
* Get the factory for this test environment, casted to {@link SessionFactoryImplementor}.
* <p/>
* Shorthand for ( {@link SessionFactoryImplementor} ) {@link #getSessions()}...
*
* @return The factory
*/
protected SessionFactoryImplementor sfi() {
return ( SessionFactoryImplementor ) getSessions();
}
protected Dialect getDialect() {
if ( dialect == null ) {
dialect = Dialect.getDialect();
}
return dialect;
}
protected Configuration getCfg() {
return cfg;
}
public org.hibernate.classic.Session openSession() throws HibernateException {
session = getSessions().openSession();
return session;
}
public org.hibernate.classic.Session openSession(Interceptor interceptor)
throws HibernateException {
session = getSessions().openSession(interceptor);
return session;
}
// JUnit hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* The Hibernate test suite tries to only build the db schema once
* per test class (not test case which = instance) hence all the
* static vars.
* <p/>
* Here is the crux of that attempt. We only build a factory when one was
* not previously built, or when we start a new test class.
*
* @throws Exception
*/
protected void setUp() throws Exception {
if ( getSessions() == null || lastTestClass != getClass() ) {
buildSessionFactory();
lastTestClass = getClass();
}
}
private void buildSessionFactory() throws Exception {
if ( getSessions()!=null ) {
getSessions().close();
}
TestCase.dialect = Dialect.getDialect();
if ( ! appliesTo( getDialect() ) ) {
return;
}
try {
TestCase.cfg = new Configuration();
cfg.setProperty( Environment.CACHE_PROVIDER, "org.hibernate.cache.HashtableCacheProvider" );
if( recreateSchema() ) {
cfg.setProperty( Environment.HBM2DDL_AUTO, "create-drop" );
}
addMappings( getMappings(), cfg );
configure( cfg );
if ( getCacheConcurrencyStrategy() != null ) {
Iterator iter = cfg.getClassMappings();
while ( iter.hasNext() ) {
PersistentClass clazz = (PersistentClass) iter.next();
Iterator props = clazz.getPropertyClosureIterator();
boolean hasLob = false;
while ( props.hasNext() ) {
Property prop = (Property) props.next();
if ( prop.getValue().isSimpleValue() ) {
String type = ( (SimpleValue) prop.getValue() ).getTypeName();
if ( "blob".equals(type) || "clob".equals(type) ) hasLob = true;
if ( Blob.class.getName().equals(type) || Clob.class.getName().equals(type) ) hasLob = true;
}
}
if ( !hasLob && !clazz.isInherited() && overrideCacheStrategy() ) {
cfg.setCacheConcurrencyStrategy(
clazz.getEntityName(),
getCacheConcurrencyStrategy()
);
}
}
iter = cfg.getCollectionMappings();
while ( iter.hasNext() ) {
Collection coll = (Collection) iter.next();
cfg.setCollectionCacheConcurrencyStrategy(
coll.getRole(),
getCacheConcurrencyStrategy()
);
}
}
// make sure we use the same dialect...
cfg.setProperty( Environment.DIALECT, TestCase.dialect.getClass().getName() );
TestCase.sessions = cfg.buildSessionFactory();
afterSessionFactoryBuilt();
}
catch ( Exception e ) {
e.printStackTrace();
throw e;
}
}
protected void addMappings(String[] files, Configuration cfg) {
for ( int i = 0; i < files.length; i++ ) {
if ( !files[i].startsWith( "net/" ) ) {
files[i] = getBaseForMappings() + files[i];
}
cfg.addResource( files[i], TestCase.class.getClassLoader() );
}
}
protected void afterSessionFactoryBuilt() throws Exception {
// for subclasses to override in order to perform extra "stuff" only
// when SF (re)built...
}
protected void runTest() throws Throwable {
final boolean stats = sessions.getStatistics().isStatisticsEnabled();
try {
if ( stats ) {
sessions.getStatistics().clear();
}
super.runTest();
if ( stats ) {
sessions.getStatistics().logSummary();
}
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
session = null;
fail( "unclosed session" );
}
else {
session = null;
}
assertAllDataRemoved();
}
catch ( Throwable e ) {
try {
if ( session != null && session.isOpen() ) {
if ( session.isConnected() ) {
session.connection().rollback();
}
session.close();
}
}
catch ( Exception ignore ) {
}
try {
if ( dropAfterFailure() && sessions != null ) {
sessions.close();
sessions = null;
}
}
catch ( Exception ignore ) {
}
throw e;
}
}
public void runBare() throws Throwable {
String sysPropName = "hibernate.test.validatefailureexpected";
assertNotNull( getName() );
if ( Boolean.getBoolean( sysPropName ) ) {
if ( getName().endsWith( "FailureExpected" ) ) {
Throwable t = null;
try {
super.runBare();
}
catch ( Throwable afe ) {
t = afe;
}
if ( t == null ) {
fail( "Test where marked as FailureExpected, but did not fail!" );
}
else {
reportSkip( "ignoring *FailuredExpected methods", "Failed with: " + t.toString() );
}
}
else {
super.runBare();
}
}
else {
super.runBare();
}
}
protected void assertAllDataRemoved() {
if ( !recreateSchema() ) {
return; // no tables were created...
}
if ( !Boolean.getBoolean( "hibernate.test.validateDataCleanup" ) ) {
return;
}
Session tmpSession = sessions.openSession();
try {
List list = tmpSession.createQuery( "select o from java.lang.Object o" ).list();
Map items = new HashMap();
if ( !list.isEmpty() ) {
for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
Object element = iter.next();
Integer l = ( Integer ) items.get( tmpSession.getEntityName( element ) );
if ( l == null ) {
l = new Integer( 0 );
}
l = new Integer( l.intValue() + 1 );
items.put( tmpSession.getEntityName( element ), l );
System.out.println( "Data left: " + element );
}
fail( "Data is left in the database: " + items.toString() );
}
}
finally {
try {
tmpSession.close();
}
catch( Throwable t ) {
// intentionally empty
}
}
}
public static void assertElementTypeAssignability(java.util.Collection collection, Class clazz) throws AssertionFailedError {
Iterator itr = collection.iterator();
while ( itr.hasNext() ) {
assertClassAssignability( itr.next().getClass(), clazz );
}
}
public static void assertClassAssignability(Class source, Class target) throws AssertionFailedError {
if ( !target.isAssignableFrom( source ) ) {
throw new AssertionFailedError(
"Classes were not assignment-compatible : source<" + source.getName() +
"> target<" + target.getName() + ">"
);
}
}
// test skipping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected static final Log SKIP_LOG = LogFactory.getLog("org.hibernate.test.SKIPPED");
public String fullTestName() {
return this.getName() + " (" + this.getClass().getName() + ")";
}
protected void reportSkip(String reason, String testDescription) {
SKIP_LOG.warn( "*** skipping [" + fullTestName() + "] - " + testDescription + " : " + reason, new Exception() );
}
/**
* Intended to indicate that this test class as a whole is intended for
* a dialect or series of dialects. Skips here (appliesTo = false) therefore
* simply indicate that the given tests target a particular feature of the
* checked database and none of the tests on this class should be run for the
* checked dialect.
*
* @param dialect The dialect to be checked.
* @return True if all the tests on this class apply to the given dialect (and
* therefore should be run); false otherwise.
*/
public boolean appliesTo(Dialect dialect) {
return true;
}
/**
* Is connection at least read committed?
* <p/>
* Not, that this skip check relies on the JDBC driver reporting
* the true isolation level correctly. HSQLDB, for example, will
* report whatever you specify as the isolation
* (Connection.setTransationIsolation()), even though it only supports
* read-uncommitted.
*
* @param scenario text description of the scenario being tested.
* @return true if read-committed isolation is maintained.
*/
protected boolean readCommittedIsolationMaintained(String scenario) {
int isolation = java.sql.Connection.TRANSACTION_READ_UNCOMMITTED;
Session testSession = null;
try {
testSession = openSession();
isolation = testSession.connection().getTransactionIsolation();
}
catch( Throwable ignore ) {
}
finally {
if ( testSession != null ) {
try {
testSession.close();
}
catch( Throwable ignore ) {
}
}
}
if ( isolation < java.sql.Connection.TRANSACTION_READ_COMMITTED ) {
reportSkip( "environment does not support at least read committed isolation", scenario );
return false;
}
else {
return true;
}
}
/**
* Does the db/dialect support using a column's physical name in the order-by clause
* even after it has been aliased in the select clause. This is not actually
* required by the SQL spec, although virtually ever DB in the world supports this
* (the most glaring omission here being IBM-variant DBs ala DB2 and Derby).
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean allowsPhysicalColumnNameInOrderby(String testDescription) {
if ( DB2Dialect.class.isInstance( getDialect() ) ) {
// https://issues.apache.org/jira/browse/DERBY-1624
reportSkip( "Dialect does not support physical column name in order-by clause after it is aliased", testDescription );
return false;
}
return true;
}
/**
* Does the db/dialect support using a column's physical name in the having clause
* even after it has been aliased in the select/group-by clause. This is not actually
* required by the SQL spec, although virtually ever DB in the world supports this.
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean allowsPhysicalColumnNameInHaving(String testDescription) {
// I only *know* of this being a limitation on Derby, although I highly suspect
// it is a limitation on any IBM/DB2 variant
if ( DerbyDialect.class.isInstance( getDialect() ) ) {
// https://issues.apache.org/jira/browse/DERBY-1624
reportSkip( "Dialect does not support physical column name in having clause after it is aliased", testDescription );
return false;
}
return true;
}
/**
* Does the db/dialect support empty lists in the IN operator?
* <p/>
* For example, is "... a.b IN () ..." supported?
*
* @param testDescription description of the scenario being tested.
* @return true if is allowed
*/
protected boolean dialectSupportsEmptyInList(String testDescription) {
if ( ! getDialect().supportsEmptyInList() ) {
reportSkip( "Dialect does not support SQL empty in list : x in ()", testDescription );
return false;
}
return true;
}
/**
* Is the db/dialect sensitive in terms of string comparisons?
* @param testDescription description of the scenario being tested.
* @return true if sensitive
*/
protected boolean dialectIsCaseSensitive(String testDescription) {
if ( getDialect().areStringComparisonsCaseInsensitive() ) {
reportSkip( "Dialect is case sensitive. ", testDescription );
return true;
}
return false;
}
protected boolean supportsRowValueConstructorSyntaxInInList() {
if ( ! getDialect().supportsRowValueConstructorSyntaxInInList() ) {
reportSkip( "Dialect does not support 'tuple' syntax as part of an IN value list", "query support" );
return false;
}
return true;
}
protected boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
if ( ! getDialect().supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() ) {
reportSkip( "Driver does not support 'position query' methods on forward-only cursors", "query support" );
return false;
}
return true;
}
protected boolean supportsCircularCascadeDelete() {
if ( ! getDialect().supportsCircularCascadeDeleteConstraints() ) {
reportSkip( "db/dialect does not support 'circular' cascade delete constraints", "cascade delete constraint support" );
return false;
}
return true;
}
protected boolean supportsSubselectOnLeftSideIn() {
if ( ! getDialect().supportsSubselectAsInPredicateLHS() ) {
reportSkip( "Database does not support (<subselect>) in ( ... ) ", "query support" );
return false;
}
return true;
}
/**
* Expected LOB usage pattern is such that I can perform an insert
* via prepared statement with a parameter binding for a LOB value
* without crazy casting to JDBC driver implementation-specific classes...
* <p/>
* Part of the trickiness here is the fact that this is largely
* driver dependent. For Oracle, which is notoriously bad with
* LOB support in their drivers actually does a pretty good job with
* LOB support as of the 10.2.x versions of their drivers...
*
* @return True if expected usage pattern is support; false otherwise.
*/
protected boolean supportsExpectedLobUsagePattern() {
if ( ! getDialect().supportsExpectedLobUsagePattern() ) {
reportSkip( "database/driver does not support expected LOB usage pattern", "LOB support" );
return false;
}
return true;
}
/**
* Does the current dialect support propogating changes to LOB
* values back to the database? Talking about mutating the
* underlying value as opposed to supplying a new
* LOB instance...
*
* @return True if the changes are propogated back to the
* database; false otherwise.
*/
protected boolean supportsLobValueChangePropogation() {
if ( ! getDialect().supportsLobValueChangePropogation() ) {
reportSkip( "database/driver does not support propogating LOB value change back to database", "LOB support" );
return false;
}
return true;
}
/**
* Is it supported to materialize a LOB locator outside the transaction in
* which it was created?
* <p/>
* Again, part of the trickiness here is the fact that this is largely
* driver dependent.
* <p/>
* NOTE: all database I have tested which {@link #supportsExpectedLobUsagePattern()}
* also support the ability to materialize a LOB outside the owning transaction...
*
* @return True if unbounded materialization is supported; false otherwise.
*/
protected boolean supportsUnboundedLobLocatorMaterialization() {
if ( !getDialect().supportsUnboundedLobLocatorMaterialization() ) {
reportSkip( "database/driver does not support materializing a LOB locator outside the 'owning' transaction", "LOB support" );
return false;
}
return true;
}
protected boolean supportsSubqueryOnMutatingTable() {
if ( !getDialect().supportsSubqueryOnMutatingTable() ) {
reportSkip( "database/driver does not support referencing mutating table in subquery", "bulk DML support" );
return false;
}
return true;
}
protected boolean dialectIs(Class dialectClass) {
return dialectClass.isInstance( getDialect() );
}
protected boolean dialectIsOneOf(Class[] dialectClasses) {
for ( int i = 0; i < dialectClasses.length; i++ ) {
if ( dialectClasses[i].isInstance( getDialect() ) ) {
return true;
}
}
return false;
}
protected boolean dialectIsNot(Class dialectClass) {
return ! dialectIs( dialectClass );
}
protected boolean dialectIsNot(Class[] dialectClasses) {
return ! dialectIsOneOf( dialectClasses );
}
}

View File

@ -0,0 +1,64 @@
package org.hibernate.test;
import java.util.Set;
import java.util.HashSet;
import java.io.File;
import org.apache.tools.ant.types.selectors.FileSelector;
import org.apache.tools.ant.BuildException;
import org.hibernate.junit.TestSuiteVisitor;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* A custom Ant FileSelector used to limit the tests run from the Ant
* build script to only those defined in the {@link org.hibernate.test.AllTests} suite.
* <p/>
* {@link org.hibernate.test.AllTests} is used/maintained by the developers to easily
* run the test suite in all IDEs. It represents all the tests
* which should actually be run and included in test results.
*
* @author Steve Ebersole
*/
public class TestSelector implements FileSelector {
private final Set allTestClassNames = new HashSet();
public TestSelector() {
TestSuiteVisitor.Handler handler = new TestSuiteVisitor.Handler() {
public void handleTestCase(Test test) {
allTestClassNames.add( test.getClass().getName() );
}
public void startingTestSuite(TestSuite suite) {}
public void completedTestSuite(TestSuite suite) {}
};
TestSuiteVisitor visitor = new TestSuiteVisitor( handler );
visitor.visit( ( TestSuite ) AllTests.suite() );
}
// FileSelector impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public boolean isSelected(File dir, String fileFromDir, File fullFile) throws BuildException {
String correspondingClassName = determineClassName( fileFromDir );
return allTestClassNames.contains( correspondingClassName );
}
private String determineClassName(String file) {
if ( file.endsWith( ".class" ) ) {
file = file.substring( 0, file.length() - 6 );
}
else if ( file.endsWith( ".java" ) ) {
file = file.substring( 0, file.length() - 5 );
}
else {
return null;
}
file = file.replace( '\\', '.' );
file = file.replace( '/', '.' );
return file;
}
}

View File

@ -0,0 +1,44 @@
package org.hibernate.test.abstractembeddedcomponents.cid;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import junit.framework.Test;
/**
* @author Steve Ebersole
*/
public class AbstractCompositeIdTest extends FunctionalTestCase {
public AbstractCompositeIdTest(String x) {
super( x );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( AbstractCompositeIdTest.class );
}
public String[] getMappings() {
return new String[] { "abstractembeddedcomponents/cid/Mappings.hbm.xml" };
}
public void testEmbeddedCompositeIdentifierOnAbstractClass() {
MyInterfaceImpl myInterface = new MyInterfaceImpl();
myInterface.setKey1( "key1" );
myInterface.setKey2( "key2" );
myInterface.setName( "test" );
Session s = openSession();
Transaction t = s.beginTransaction();
s.save( myInterface );
s.flush();
s.createQuery( "from MyInterface" ).list();
s.delete( myInterface );
t.commit();
s.close();
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.abstractembeddedcomponents.cid">
<class name="MyInterface" table="MY_INTF" proxy="MyInterface">
<composite-id>
<key-property name="key1" type="string"/>
<key-property name="key2" type="string"/>
</composite-id>
<discriminator column="TYPE" type="string" length="10"/>
<property name="name" type="string"/>
</class>
<subclass name="MyInterfaceImpl" extends="MyInterface" discriminator-value="1" proxy="MyInterface">
</subclass>
</hibernate-mapping>

View File

@ -0,0 +1,15 @@
package org.hibernate.test.abstractembeddedcomponents.cid;
import java.io.Serializable;
/**
* @author Steve Ebersole
*/
public interface MyInterface extends Serializable {
public String getKey1();
public void setKey1(String key1);
public String getKey2();
public void setKey2(String key2);
public String getName();
public void setName(String name);
}

View File

@ -0,0 +1,36 @@
package org.hibernate.test.abstractembeddedcomponents.cid;
import org.hibernate.test.abstractembeddedcomponents.cid.MyInterface;
/**
* @author Steve Ebersole
*/
public class MyInterfaceImpl implements MyInterface {
private String key1;
private String key2;
private String name;
public String getKey1() {
return key1;
}
public void setKey1(String key1) {
this.key1 = key1;
}
public String getKey2() {
return key2;
}
public void setKey2(String key2) {
this.key2 = key2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,49 @@
package org.hibernate.test.abstractembeddedcomponents.propertyref;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import junit.framework.Test;
/**
* @author Steve Ebersole
*/
public class AbstractComponentPropertyRefTest extends FunctionalTestCase {
public AbstractComponentPropertyRefTest(String name) {
super( name );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( AbstractComponentPropertyRefTest.class );
}
public String[] getMappings() {
return new String[] { "abstractembeddedcomponents/propertyref/Mappings.hbm.xml" };
}
public void testPropertiesRefCascades() {
Session session = openSession();
Transaction trans = session.beginTransaction();
ServerImpl server = new ServerImpl();
session.save( server );
AddressImpl address = new AddressImpl();
server.setAddress( address );
address.setServer( server );
session.flush();
session.createQuery( "from Server s join fetch s.address" ).list();
trans.commit();
session.close();
assertNotNull( server.getId() );
assertNotNull( address.getId() );
session = openSession();
trans = session.beginTransaction();
session.delete( address );
session.delete( server );
trans.commit();
session.close();
}
}

View File

@ -0,0 +1,13 @@
package org.hibernate.test.abstractembeddedcomponents.propertyref;
/**
* @author Steve Ebersole
*/
public interface Address {
public Long getId();
public void setId(Long id);
public String getAddressType();
public void setAddressType(String addressType);
public Server getServer();
public void setServer(Server server);
}

View File

@ -0,0 +1,36 @@
package org.hibernate.test.abstractembeddedcomponents.propertyref;
import org.hibernate.test.abstractembeddedcomponents.propertyref.Address;
/**
* @author Steve Ebersole
*/
public class AddressImpl implements Address {
private Long id;
private String addressType;
private Server server;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAddressType() {
return addressType;
}
public void setAddressType(String addressType) {
this.addressType = addressType;
}
public Server getServer() {
return server;
}
public void setServer(Server server) {
this.server = server;
}
}

View File

@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.abstractembeddedcomponents.propertyref">
<class name="Address" table="ADDRESS" proxy="Address">
<id name="id" type="long" column="ADDRESS_ID">
<generator class="native"/>
</id>
<discriminator column="ADDRESS_TYPE" type="string" length="30"/>
<properties name="uniqueAddress">
<property name="addressType" column="ADDRESS_TYPE" type="string" insert="false" update="false" length="30"/>
<many-to-one name="server" column="SERVER_ID" class="Server" not-null="true"/>
</properties>
</class>
<subclass name="AddressImpl" extends="Address" discriminator-value="2" proxy="Address">
</subclass>
<class name="Server" table="SERVER" proxy="Server">
<id name="id" type="long" column="SERVER_ID">
<generator class="native"/>
</id>
<discriminator column="SERVER_TYPE" type="string" length="10"/>
<property name="serverType" type="string" column="SERVER_TYPE" length="10" update="false" insert="false"/>
</class>
<subclass name="ServerImpl" extends="Server" discriminator-value="1" proxy="Server">
<many-to-one name="address"
class="AddressImpl"
property-ref="uniqueAddress"
cascade="all"
unique="true"
update="false"
insert="false">
<column name="ADDRESS_TYPE"/>
<column name="SERVER_ID"/>
</many-to-one>
</subclass>
</hibernate-mapping>

View File

@ -0,0 +1,15 @@
package org.hibernate.test.abstractembeddedcomponents.propertyref;
import org.hibernate.test.abstractembeddedcomponents.propertyref.Address;
/**
* @author Steve Ebersole
*/
public interface Server {
public Long getId();
public void setId(Long id);
public String getServerType();
public void setServerType(String serverType);
public Address getAddress();
public void setAddress(Address address);
}

View File

@ -0,0 +1,37 @@
package org.hibernate.test.abstractembeddedcomponents.propertyref;
import org.hibernate.test.abstractembeddedcomponents.propertyref.Address;
import org.hibernate.test.abstractembeddedcomponents.propertyref.Server;
/**
* @author Steve Ebersole
*/
public class ServerImpl implements Server {
private Long id;
private String serverType;
private Address address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getServerType() {
return serverType;
}
public void setServerType(String serverType) {
this.serverType = serverType;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

View File

@ -0,0 +1,30 @@
package org.hibernate.test.any;
import java.util.Set;
import java.util.HashSet;
/**
* todo: describe Address
*
* @author Steve Ebersole
*/
public class Address {
private Long id;
private Set lines = new HashSet();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set getLines() {
return lines;
}
public void setLines(Set lines) {
this.lines = lines;
}
}

View File

@ -0,0 +1,59 @@
package org.hibernate.test.any;
import org.hibernate.Session;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.junit.functional.FunctionalTestCase;
import junit.framework.Test;
/**
* todo: describe AnyTypeTest
*
* @author Steve Ebersole
*/
public class AnyTypeTest extends FunctionalTestCase {
public AnyTypeTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "any/Person.hbm.xml" };
}
public String getCacheConcurrencyStrategy() {
// having second level cache causes a condition whereby the original test case would not fail...
return null;
}
public static Test suite() {
return new FunctionalTestClassTestSuite( AnyTypeTest.class );
}
/**
* Specific test for HHH-1663...
*/
public void testFlushProcessing() {
Session session = openSession();
session.beginTransaction();
Person person = new Person();
Address address = new Address();
person.setData( address );
session.saveOrUpdate(person);
session.saveOrUpdate(address);
session.getTransaction().commit();
session.close();
session = openSession();
session.beginTransaction();
person = (Person) session.load( Person.class, person.getId() );
person.setName("makingpersondirty");
session.getTransaction().commit();
session.close();
session = openSession();
session.beginTransaction();
session.delete( person );
session.getTransaction().commit();
session.close();
}
}

View File

@ -0,0 +1,47 @@
package org.hibernate.test.any;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
/**
* todo: describe ${NAME}
*
* @author Steve Ebersole
*/
public class ComplexPropertyValue implements PropertyValue {
private Long id;
private Map subProperties = new HashMap();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Map getSubProperties() {
return subProperties;
}
public void setSubProperties(Map subProperties) {
this.subProperties = subProperties;
}
public String asString() {
return "complex[" + keyString() + "]";
}
private String keyString() {
StringBuffer buff = new StringBuffer();
Iterator itr = subProperties.keySet().iterator();
while ( itr.hasNext() ) {
buff.append( itr.next() );
if ( itr.hasNext() ) {
buff.append( ", " );
}
}
return buff.toString();
}
}

View File

@ -0,0 +1,38 @@
package org.hibernate.test.any;
/**
* todo: describe IntegerPropertyValue
*
* @author Steve Ebersole
*/
public class IntegerPropertyValue implements PropertyValue {
private Long id;
private int value;
public IntegerPropertyValue() {
}
public IntegerPropertyValue(int value) {
this.value = value;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public String asString() {
return Integer.toString( value );
}
}

View File

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.any">
<class name="Person" table="T_ANY_PERSON">
<id name="id" column="ID_">
<generator class="increment" />
</id>
<property name="name" />
<any name="data" id-type="long" cascade="none">
<meta-value value="A" class="Address"/>
<column name="DATATYPE_"/>
<column name="DATAID_"/>
</any>
</class>
<class name="Address" table="T_ANY_ADDRESS">
<id name="id" column="ID_">
<generator class="increment" />
</id>
<set name="lines" table="LINE">
<key column="ADDRESS" />
<element type="string" />
</set>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,37 @@
package org.hibernate.test.any;
/**
* todo: describe Person
*
* @author Steve Ebersole
*/
public class Person {
private Long id;
private String name;
private Object data;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,56 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.any">
<class name="PropertySet" table="T_PROP_SET">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string"/>
<any name="someSpecificProperty" id-type="long" meta-type="string" cascade="all">
<meta-value value="I" class="IntegerPropertyValue"/>
<meta-value value="S" class="StringPropertyValue"/>
<meta-value value="C" class="ComplexPropertyValue" />
<column name="S_S_PROP_TYPE"/>
<column name="S_S_PROP_ID"/>
</any>
<map name="generalProperties" table="T_GEN_PROPS" lazy="true" cascade="all">
<key column="PROP_SET_ID"/>
<map-key type="string" column="GEN_PROP_NAME"/>
<many-to-any id-type="long" meta-type="string">
<meta-value value="I" class="IntegerPropertyValue"/>
<meta-value value="S" class="StringPropertyValue"/>
<column name="PROP_TYPE"/>
<column name="PROP_ID"/>
</many-to-any>
</map>
</class>
<class name="StringPropertyValue" table="T_CHAR_PROP">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="value" column="VAL" not-null="true" type="string"/>
</class>
<class name="IntegerPropertyValue" table="T_NUM_PROP">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<property name="value" column="VAL" not-null="true" type="integer"/>
</class>
<class name="ComplexPropertyValue" table="T_COMPLEX_PROP">
<id name="id" column="ID" type="long">
<generator class="increment"/>
</id>
<map name="subProperties" table="T_COMPLEX_SUB_PROPS" lazy="true">
<key column="PROP_ID" />
<map-key type="string" column="SUB_PROP_NAME" />
<element type="string" column="SUB_PROP_VAL" />
</map>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,55 @@
package org.hibernate.test.any;
import java.util.Map;
import java.util.HashMap;
/**
* todo: describe PropertySet
*
* @author Steve Ebersole
*/
public class PropertySet {
private Long id;
private String name;
private PropertyValue someSpecificProperty;
private Map generalProperties = new HashMap();
public PropertySet() {
}
public PropertySet(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PropertyValue getSomeSpecificProperty() {
return someSpecificProperty;
}
public void setSomeSpecificProperty(PropertyValue someSpecificProperty) {
this.someSpecificProperty = someSpecificProperty;
}
public Map getGeneralProperties() {
return generalProperties;
}
public void setGeneralProperties(Map generalProperties) {
this.generalProperties = generalProperties;
}
}

View File

@ -0,0 +1,10 @@
package org.hibernate.test.any;
/**
* todo: describe PropertyValue
*
* @author Steve Ebersole
*/
public interface PropertyValue {
public String asString();
}

View File

@ -0,0 +1,38 @@
package org.hibernate.test.any;
/**
* todo: describe StringPropertyValue
*
* @author Steve Ebersole
*/
public class StringPropertyValue implements PropertyValue {
private Long id;
private String value;
public StringPropertyValue() {
}
public StringPropertyValue(String value) {
this.value = value;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String asString() {
return value;
}
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
This mapping demonstrates content-based discrimination for the
table-per-hierarchy mapping strategy, using a formula
discriminator.
-->
<hibernate-mapping
package="org.hibernate.test.array">
<class name="A" lazy="true" table="aaa">
<id name="id">
<generator class="native"/>
</id>
<array name="bs" cascade="all" fetch="join">
<key column="a_id"/>
<list-index column="idx"/>
<one-to-many class="B"/>
</array>
</class>
<class name="B" lazy="true" table="bbb">
<id name="id">
<generator class="native"/>
</id>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,26 @@
//$Id$
package org.hibernate.test.array;
/**
* @author Emmanuel Bernard
*/
public class A {
private Integer id;
private B[] bs;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public B[] getBs() {
return bs;
}
public void setBs(B[] bs) {
this.bs = bs;
}
}

View File

@ -0,0 +1,53 @@
//$Id$
package org.hibernate.test.array;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* @author Emmanuel Bernard
*/
public class ArrayTest extends FunctionalTestCase {
public ArrayTest(String x) {
super( x );
}
public String[] getMappings() {
return new String[] { "array/A.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( ArrayTest.class );
}
public void testArrayJoinFetch() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
A a = new A();
B b = new B();
a.setBs( new B[] {b} );
s.persist( a );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
a = (A) s.get( A.class, a.getId() );
assertNotNull( a );
assertNotNull( a.getBs() );
assertEquals( a.getBs().length, 1 );
assertNotNull( a.getBs()[0] );
s.delete(a);
s.delete(a.getBs()[0]);
tx.commit();
s.close();
}
}

View File

@ -0,0 +1,17 @@
//$Id$
package org.hibernate.test.array;
/**
* @author Emmanuel Bernard
*/
public class B {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

View File

@ -0,0 +1,120 @@
// $Id$
package org.hibernate.test.ast;
import java.io.PrintWriter;
import antlr.ASTFactory;
import antlr.collections.AST;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.hql.antlr.HqlTokenTypes;
import org.hibernate.hql.ast.HqlParser;
import org.hibernate.hql.ast.util.ASTIterator;
import org.hibernate.hql.ast.util.ASTParentsFirstIterator;
import org.hibernate.hql.ast.util.ASTPrinter;
import org.hibernate.hql.ast.util.ASTUtil;
import org.hibernate.junit.UnitTestCase;
/**
* Test ASTIterator.
*/
public class ASTIteratorTest extends UnitTestCase {
private ASTFactory factory;
/**
* Standard JUnit test case constructor.
*
* @param name The name of the test case.
*/
public ASTIteratorTest(String name) {
super( name );
}
public static Test suite() {
return new TestSuite( ASTIteratorTest.class );
}
protected void setUp() throws Exception {
super.setUp();
factory = new ASTFactory();
}
/**
* Test a simple tree, make sure the iterator encounters every node.
*/
public void testSimpleTree() throws Exception {
String input = "select foo from foo in class org.hibernate.test.Foo, fee in class org.hibernate.test.Fee where foo.dependent = fee order by foo.string desc, foo.component.count asc, fee.id";
HqlParser parser = HqlParser.getInstance( input );
parser.statement();
AST ast = parser.getAST();
ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
printer.showAst( ast, new PrintWriter( System.out ) );
ASTIterator iterator = new ASTIterator( ast );
int count = 0;
while ( iterator.hasNext() ) {
assertTrue( iterator.next() instanceof AST );
count++;
}
assertEquals( 43, count );
UnsupportedOperationException uoe = null;
try {
iterator.remove();
}
catch ( UnsupportedOperationException e ) {
uoe = e;
}
assertNotNull( uoe );
}
public void testParentsFirstIterator() throws Exception {
AST[] tree = new AST[4];
AST grandparent = tree[0] = ASTUtil.create( factory, 1, "grandparent" );
AST parent = tree[1] = ASTUtil.create( factory, 2, "parent" );
AST child = tree[2] = ASTUtil.create( factory, 3, "child" );
AST baby = tree[3] = ASTUtil.create( factory, 4, "baby" );
AST t = ASTUtil.createTree( factory, tree );
AST brother = ASTUtil.create( factory, 10, "brother" );
child.setNextSibling( brother );
AST sister = ASTUtil.create( factory, 11, "sister" );
brother.setNextSibling( sister );
AST uncle = factory.make( new AST[]{
factory.create( 20, "uncle" ),
factory.create( 21, "cousin1" ),
factory.create( 22, "cousin2" ),
factory.create( 23, "cousin3" )} );
parent.setNextSibling( uncle );
System.out.println( t.toStringTree() );
System.out.println( "--- ASTParentsFirstIterator ---" );
ASTParentsFirstIterator iter = new ASTParentsFirstIterator( t );
int count = 0;
while ( iter.hasNext() ) {
AST n = iter.nextNode();
count++;
System.out.println( n );
}
assertEquals( 10, count );
System.out.println( "--- ASTIterator ---" );
ASTIterator iter2 = new ASTIterator( t );
int count2 = 0;
while ( iter2.hasNext() ) {
AST n = iter2.nextNode();
count2++;
System.out.println( n );
}
assertEquals( 10, count2 );
System.out.println( "--- ASTParentsFirstIterator (parent) ---" );
ASTParentsFirstIterator iter3 = new ASTParentsFirstIterator( parent );
int count3 = 0;
while ( iter3.hasNext() ) {
AST n = iter3.nextNode();
count3++;
System.out.println( n );
}
assertEquals( 5, count3 );
}
}

View File

@ -0,0 +1,77 @@
// $Id$
package org.hibernate.test.ast;
import antlr.ASTFactory;
import antlr.collections.AST;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.hql.ast.util.ASTUtil;
import org.hibernate.junit.UnitTestCase;
/**
* Unit test for ASTUtil.
*/
public class ASTUtilTest extends UnitTestCase {
private ASTFactory factory;
/**
* Standard JUnit test case constructor.
*
* @param name The name of the test case.
*/
public ASTUtilTest(String name) {
super( name );
}
protected void setUp() throws Exception {
super.setUp();
factory = new ASTFactory();
}
public void testCreate() throws Exception {
AST n = ASTUtil.create( factory, 1, "one");
assertNull( n.getFirstChild() );
assertEquals("one",n.getText());
assertEquals(1,n.getType());
}
/**
* Test adding a tree of children.
*/
public void testCreateTree() throws Exception {
AST[] tree = new AST[4];
AST grandparent = tree[0] = ASTUtil.create(factory, 1, "grandparent");
AST parent = tree[1] = ASTUtil.create(factory,2,"parent");
AST child = tree[2] = ASTUtil.create(factory,3,"child");
AST baby = tree[3] = ASTUtil.create(factory,4,"baby");
AST t = ASTUtil.createTree( factory, tree);
assertSame(t,grandparent);
assertSame(parent,t.getFirstChild());
assertSame(child,t.getFirstChild().getFirstChild());
assertSame(baby,t.getFirstChild().getFirstChild().getFirstChild());
}
public void testFindPreviousSibling() throws Exception {
AST child1 = ASTUtil.create(factory,2, "child1");
AST child2 = ASTUtil.create(factory,3, "child2");
AST n = factory.make( new AST[] {
ASTUtil.create(factory, 1, "parent"),
child1,
child2,
});
assertSame(child1,ASTUtil.findPreviousSibling( n,child2));
Exception e = null;
try {
ASTUtil.findPreviousSibling(child1,null);
}
catch (Exception x) {
e = x;
}
assertNotNull(e);
}
public static Test suite() {
return new TestSuite( ASTUtilTest.class );
}
}

View File

@ -0,0 +1,89 @@
//$Id$
package org.hibernate.test.batch;
import java.math.BigDecimal;
import junit.framework.Test;
import org.hibernate.CacheMode;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
/**
* This is how to do batch processing in Hibernate.
* Remember to enable JDBC batch updates, or this
* test will take a Very Long Time!
*
* @author Gavin King
*/
public class BatchTest extends FunctionalTestCase {
public BatchTest(String str) {
super( str );
}
public String[] getMappings() {
return new String[] { "batch/DataPoint.hbm.xml" };
}
public String getCacheConcurrencyStrategy() {
return null;
}
public void configure(Configuration cfg) {
cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "20" );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( BatchTest.class );
}
public void testBatchInsertUpdate() {
long start = System.currentTimeMillis();
final int N = 5000; //26 secs with batch flush, 26 without
//final int N = 100000; //53 secs with batch flush, OOME without
//final int N = 250000; //137 secs with batch flush, OOME without
Session s = openSession();
s.setCacheMode( CacheMode.IGNORE );
Transaction t = s.beginTransaction();
for ( int i = 0; i < N; i++ ) {
DataPoint dp = new DataPoint();
dp.setX( new BigDecimal( i * 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN ) );
dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
s.save( dp );
if ( i % 20 == 0 ) {
s.flush();
s.clear();
}
}
t.commit();
s.close();
s = openSession();
s.setCacheMode( CacheMode.IGNORE );
t = s.beginTransaction();
int i = 0;
ScrollableResults sr = s.createQuery( "from DataPoint dp order by dp.x asc" )
.scroll( ScrollMode.FORWARD_ONLY );
while ( sr.next() ) {
DataPoint dp = ( DataPoint ) sr.get( 0 );
dp.setDescription( "done!" );
if ( ++i % 20 == 0 ) {
s.flush();
s.clear();
}
}
t.commit();
s.close();
System.out.println( System.currentTimeMillis() - start );
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.batch">
<class name="DataPoint"
dynamic-update="true">
<!--rowid="rowid"--> <!-- remove this if not oracle -->
<id name="id">
<generator class="increment"/>
</id>
<property name="x">
<column name="xval" not-null="true" length="4" unique-key="xy"/>
</property>
<property name="y">
<column name="yval" not-null="true" length="4" unique-key="xy"/>
</property>
<property name="description"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,62 @@
//$Id$
package org.hibernate.test.batch;
import java.math.BigDecimal;
/**
* @author Gavin King
*/
public class DataPoint {
private long id;
private BigDecimal x;
private BigDecimal y;
private String description;
/**
* @return Returns the description.
*/
public String getDescription() {
return description;
}
/**
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* @return Returns the id.
*/
public long getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(long id) {
this.id = id;
}
/**
* @return Returns the x.
*/
public BigDecimal getX() {
return x;
}
/**
* @param x The x to set.
*/
public void setX(BigDecimal x) {
this.x = x;
}
/**
* @return Returns the y.
*/
public BigDecimal getY() {
return y;
}
/**
* @param y The y to set.
*/
public void setY(BigDecimal y) {
this.y = y;
}
}

View File

@ -0,0 +1,122 @@
//$Id$
package org.hibernate.test.batchfetch;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* @author Gavin King
*/
public class BatchFetchTest extends FunctionalTestCase {
public BatchFetchTest(String str) {
super( str );
}
public String[] getMappings() {
return new String[] { "batchfetch/ProductLine.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( BatchFetchTest.class );
}
public void testBatchFetch() {
Session s = openSession();
Transaction t = s.beginTransaction();
ProductLine cars = new ProductLine();
cars.setDescription( "Cars" );
Model monaro = new Model( cars );
monaro.setName( "monaro" );
monaro.setDescription( "Holden Monaro" );
Model hsv = new Model( cars );
hsv.setName( "hsv" );
hsv.setDescription( "Holden Commodore HSV" );
s.save( cars );
ProductLine oss = new ProductLine();
oss.setDescription( "OSS" );
Model jboss = new Model( oss );
jboss.setName( "JBoss" );
jboss.setDescription( "JBoss Application Server" );
Model hibernate = new Model( oss );
hibernate.setName( "Hibernate" );
hibernate.setDescription( "Hibernate" );
Model cache = new Model( oss );
cache.setName( "JBossCache" );
cache.setDescription( "JBoss TreeCache" );
s.save( oss );
t.commit();
s.close();
s.getSessionFactory().evict( Model.class );
s.getSessionFactory().evict( ProductLine.class );
s = openSession();
t = s.beginTransaction();
List list = s.createQuery( "from ProductLine pl order by pl.description" ).list();
cars = ( ProductLine ) list.get( 0 );
oss = ( ProductLine ) list.get( 1 );
assertFalse( Hibernate.isInitialized( cars.getModels() ) );
assertFalse( Hibernate.isInitialized( oss.getModels() ) );
assertEquals( cars.getModels().size(), 2 ); //fetch both collections
assertTrue( Hibernate.isInitialized( cars.getModels() ) );
assertTrue( Hibernate.isInitialized( oss.getModels() ) );
s.clear();
list = s.createQuery( "from Model m" ).list();
hibernate = ( Model ) s.get( Model.class, hibernate.getId() );
hibernate.getProductLine().getId();
for ( Iterator i = list.iterator(); i.hasNext(); ) {
assertFalse( Hibernate.isInitialized( ( ( Model ) i.next() ).getProductLine() ) );
}
assertEquals( hibernate.getProductLine().getDescription(), "OSS" ); //fetch both productlines
s.clear();
Iterator iter = s.createQuery( "from Model" ).iterate();
list = new ArrayList();
while ( iter.hasNext() ) {
list.add( iter.next() );
}
Model m = ( Model ) list.get( 0 );
m.getDescription(); //fetch a batch of 4
s.clear();
list = s.createQuery( "from ProductLine" ).list();
ProductLine pl = ( ProductLine ) list.get( 0 );
ProductLine pl2 = ( ProductLine ) list.get( 1 );
s.evict( pl2 );
pl.getModels().size(); //fetch just one collection! (how can we write an assertion for that??)
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
list = s.createQuery( "from ProductLine pl order by pl.description" ).list();
cars = ( ProductLine ) list.get( 0 );
oss = ( ProductLine ) list.get( 1 );
assertEquals( cars.getModels().size(), 2 );
assertEquals( oss.getModels().size(), 3 );
s.delete( cars );
s.delete( oss );
t.commit();
s.close();
}
}

View File

@ -0,0 +1,44 @@
//$Id$
package org.hibernate.test.batchfetch;
/**
* @author Gavin King
*/
public class Model {
private String id;
private String name;
private String description;
private ProductLine productLine;
Model() {}
public Model(ProductLine pl) {
this.productLine = pl;
pl.getModels().add(this);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ProductLine getProductLine() {
return productLine;
}
public void setProductLine(ProductLine productLine) {
this.productLine = productLine;
}
}

View File

@ -0,0 +1,61 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.batchfetch">
<!--
This mapping demonstrates the use of batch fetching
for collections and entities.
-->
<class name="ProductLine"
batch-size="64">
<id name="id"
column="productId"
length="32">
<generator class="uuid.hex"/>
</id>
<property name="description"
not-null="true"
length="200"/>
<set name="models"
batch-size="64"
cascade="all"
inverse="true">
<key column="productId"/>
<one-to-many class="Model"/>
</set>
</class>
<class name="Model"
batch-size="64">
<id name="id"
column="modelId"
length="32">
<generator class="uuid.hex"/>
</id>
<property name="name"
not-null="true"
length="25"/>
<property name="description"
not-null="true"
length="200"/>
<many-to-one name="productLine"
column="productId"
not-null="true"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,34 @@
//$Id$
package org.hibernate.test.batchfetch;
import java.util.HashSet;
import java.util.Set;
/**
* @author Gavin King
*/
public class ProductLine {
private String id;
private String description;
private Set models = new HashSet();
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Set getModels() {
return models;
}
public void setModels(Set models) {
this.models = models;
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.bidi">
<class name="Auction" table="TAuction">
<id name="id">
<generator class="native"/>
</id>
<property name="description"/>
<property name="end" column="endDatetime"/>
<bag name="bids" inverse="true"
cascade="persist">
<key column="auctionId"/>
<one-to-many class="Bid"/>
</bag>
<one-to-one name="successfulBid"
property-ref="abc">
<formula>id</formula>
<formula>1</formula>
</one-to-one>
</class>
<class name="Bid" table="TBid">
<id name="id">
<generator class="native"/>
</id>
<property name="amount"
scale="19"
precision="31" />
<property name="datetime"
column="createdDatetime"/>
<properties name="abc">
<many-to-one name="item"
column="auctionId"
cascade="persist"/>
<property name="successful"
column="success"/>
</properties>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,48 @@
//$Id$
package org.hibernate.test.bidi;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Gavin King
*/
public class Auction {
private Long id;
private String description;
private List bids = new ArrayList();
private Bid successfulBid;
private Date end;
public Date getEnd() {
return end;
}
public void setEnd(Date end) {
this.end = end;
}
public List getBids() {
return bids;
}
public void setBids(List bids) {
this.bids = bids;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Bid getSuccessfulBid() {
return successfulBid;
}
public void setSuccessfulBid(Bid successfulBid) {
this.successfulBid = successfulBid;
}
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.bidi">
<class name="Auction" table="TAuction2">
<id name="id">
<generator class="native"/>
</id>
<property name="description"/>
<property name="end" column="endDatetime"/>
<bag name="bids" inverse="true"
cascade="persist">
<key column="auctionId"/>
<one-to-many class="Bid"/>
</bag>
<many-to-one name="successfulBid"/>
</class>
<class name="Bid" table="TBid2">
<id name="id">
<generator class="native"/>
</id>
<property name="amount" scale="19" precision="31"/>
<property name="datetime"
column="createdDatetime"/>
<many-to-one name="item"
column="auctionId"
cascade="persist"/>
<property name="successful">
<formula>exists(select a.id from TAuction2 a where a.successfulBid=id)</formula>
</property>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,119 @@
//$Id$
package org.hibernate.test.bidi;
import java.math.BigDecimal;
import java.util.Date;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.dialect.PostgreSQLDialect;
/**
* @author Gavin King
*/
public class AuctionTest extends FunctionalTestCase {
public AuctionTest(String str) {
super( str );
}
public String[] getMappings() {
return new String[] { "bidi/Auction.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( AuctionTest.class );
}
public void testLazy() {
if ( getDialect() instanceof PostgreSQLDialect ) {
return; //doesn't like boolean=1
}
Session s = openSession();
Transaction t = s.beginTransaction();
Auction a = new Auction();
a.setDescription( "an auction for something" );
a.setEnd( new Date() );
Bid b = new Bid();
b.setAmount( new BigDecimal( 123.34 ).setScale( 19, BigDecimal.ROUND_DOWN ) );
b.setSuccessful( true );
b.setDatetime( new Date() );
b.setItem( a );
a.getBids().add( b );
a.setSuccessfulBid( b );
s.persist( b );
t.commit();
s.close();
Long aid = a.getId();
Long bid = b.getId();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
assertFalse( Hibernate.isInitialized( b ) );
a = ( Auction ) s.get( Auction.class, aid );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertTrue( Hibernate.isInitialized( a.getSuccessfulBid() ) );
assertSame( a.getBids().iterator().next(), b );
assertSame( b, a.getSuccessfulBid() );
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
assertFalse( Hibernate.isInitialized( b ) );
a = ( Auction ) s.createQuery( "from Auction a left join fetch a.bids" ).uniqueResult();
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( Hibernate.isInitialized( a.getBids() ) );
assertSame( b, a.getSuccessfulBid() );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
a = ( Auction ) s.load( Auction.class, aid );
assertFalse( Hibernate.isInitialized( b ) );
assertFalse( Hibernate.isInitialized( a ) );
s.createQuery( "from Auction a left join fetch a.successfulBid" ).list();
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( Hibernate.isInitialized( a ) );
assertSame( b, a.getSuccessfulBid() );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
a = ( Auction ) s.load( Auction.class, aid );
assertFalse( Hibernate.isInitialized( b ) );
assertFalse( Hibernate.isInitialized( a ) );
assertSame( s.get( Bid.class, bid ), b );
assertTrue( Hibernate.isInitialized( b ) );
assertSame( s.get( Auction.class, aid ), a );
assertTrue( Hibernate.isInitialized( a ) );
assertSame( b, a.getSuccessfulBid() );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
}
}

View File

@ -0,0 +1,123 @@
//$Id$
package org.hibernate.test.bidi;
import java.math.BigDecimal;
import java.util.Date;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.dialect.Oracle9Dialect;
import junit.framework.Test;
/**
* @author Gavin King
*/
public class AuctionTest2 extends FunctionalTestCase {
public AuctionTest2(String str) {
super( str );
}
public String[] getMappings() {
return new String[] { "bidi/Auction2.hbm.xml" };
}
public boolean createSchema() {
return getDialect().supportsExistsInSelect();
}
public static Test suite() {
return new FunctionalTestClassTestSuite( AuctionTest2.class );
}
public void testLazy() {
if ( ! getDialect().supportsExistsInSelect() ) {
reportSkip( "dialect does not support exist fragments in the select clause", "bidi support" );
return;
}
Session s = openSession();
Transaction t = s.beginTransaction();
Auction a = new Auction();
a.setDescription( "an auction for something" );
a.setEnd( new Date() );
Bid b = new Bid();
b.setAmount( new BigDecimal( 123.34 ).setScale( 19, BigDecimal.ROUND_DOWN ) );
b.setSuccessful( true );
b.setDatetime( new Date() );
b.setItem( a );
a.getBids().add( b );
a.setSuccessfulBid( b );
s.persist( b );
t.commit();
s.close();
Long aid = a.getId();
Long bid = b.getId();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
assertFalse( Hibernate.isInitialized( b ) );
a = ( Auction ) s.get( Auction.class, aid );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertFalse( Hibernate.isInitialized( a.getSuccessfulBid() ) );
assertSame( a.getBids().iterator().next(), b );
assertSame( b, a.getSuccessfulBid() );
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
assertFalse( Hibernate.isInitialized( b ) );
a = ( Auction ) s.createQuery( "from Auction a left join fetch a.bids" ).uniqueResult();
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( Hibernate.isInitialized( a.getBids() ) );
assertSame( b, a.getSuccessfulBid() );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
a = ( Auction ) s.load( Auction.class, aid );
assertFalse( Hibernate.isInitialized( b ) );
assertFalse( Hibernate.isInitialized( a ) );
s.createQuery( "from Auction a left join fetch a.successfulBid" ).list();
assertTrue( Hibernate.isInitialized( b ) );
assertTrue( Hibernate.isInitialized( a ) );
assertSame( b, a.getSuccessfulBid() );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
b = ( Bid ) s.load( Bid.class, bid );
a = ( Auction ) s.load( Auction.class, aid );
assertFalse( Hibernate.isInitialized( b ) );
assertFalse( Hibernate.isInitialized( a ) );
assertSame( s.get( Bid.class, bid ), b );
assertTrue( Hibernate.isInitialized( b ) );
assertSame( s.get( Auction.class, aid ), a );
assertTrue( Hibernate.isInitialized( a ) );
assertSame( b, a.getSuccessfulBid() );
assertFalse( Hibernate.isInitialized( a.getBids() ) );
assertSame( a.getBids().iterator().next(), b );
assertTrue( b.isSuccessful() );
t.commit();
s.close();
}
}

View File

@ -0,0 +1,47 @@
//$Id$
package org.hibernate.test.bidi;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author Gavin King
*/
public class Bid {
private Long id;
private Auction item;
private BigDecimal amount;
private boolean successful;
private Date datetime;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Auction getItem() {
return item;
}
public void setItem(Auction item) {
this.item = item;
}
public boolean isSuccessful() {
return successful;
}
public void setSuccessful(boolean successful) {
this.successful = successful;
}
public Date getDatetime() {
return datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.bytecode">
<class name="Bean">
<id name="someString" type="string">
<generator class="assigned"/>
</id>
<property name="someLong" type="long" column="S_LONG_1" />
<property name="someInteger" type="int" column="S_INT_1" />
<property name="someDate" type="timestamp" column="S_DATE_1" />
<property name="somelong" type="long" column="S_LONG_2" />
<property name="someint" type="int" column="S_INT_2" />
<property name="someObject" type="serializable" column="S_OBJ_1" />
</class>
<class name="ProxyBean" lazy="true">
<id name="someString" type="string">
<generator class="assigned"/>
</id>
<property name="someLong" type="long" column="S_LONG_1" />
</class>
</hibernate-mapping>

View File

@ -0,0 +1,78 @@
package org.hibernate.test.bytecode;
import java.util.Date;
import java.text.ParseException;
/**
* @author Steve Ebersole
*/
public class Bean {
private String someString;
private Long someLong;
private Integer someInteger;
private Date someDate;
private long somelong;
private int someint;
private Object someObject;
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
public Long getSomeLong() {
return someLong;
}
public void setSomeLong(Long someLong) {
this.someLong = someLong;
}
public Integer getSomeInteger() {
return someInteger;
}
public void setSomeInteger(Integer someInteger) {
this.someInteger = someInteger;
}
public Date getSomeDate() {
return someDate;
}
public void setSomeDate(Date someDate) {
this.someDate = someDate;
}
public long getSomelong() {
return somelong;
}
public void setSomelong(long somelong) {
this.somelong = somelong;
}
public int getSomeint() {
return someint;
}
public void setSomeint(int someint) {
this.someint = someint;
}
public Object getSomeObject() {
return someObject;
}
public void setSomeObject(Object someObject) {
this.someObject = someObject;
}
public void throwException() throws ParseException {
throw new ParseException( "you asked for it...", 0 );
}
}

View File

@ -0,0 +1,78 @@
package org.hibernate.test.bytecode;
import org.hibernate.property.BasicPropertyAccessor;
import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import java.util.Date;
/**
* @author Steve Ebersole
*/
public class BeanReflectionHelper {
public static final Object[] TEST_VALUES = new Object[] {
"hello", new Long(1), new Integer(1), new Date(), new Long(1), new Integer(1), new Object()
};
private static final String[] getterNames = new String[7];
private static final String[] setterNames = new String[7];
private static final Class[] types = new Class[7];
static {
BasicPropertyAccessor propertyAccessor = new BasicPropertyAccessor();
Getter getter = propertyAccessor.getGetter( Bean.class, "someString" );
Setter setter = propertyAccessor.getSetter( Bean.class, "someString" );
getterNames[0] = getter.getMethodName();
types[0] = getter.getReturnType();
setterNames[0] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "someLong" );
setter = propertyAccessor.getSetter( Bean.class, "someLong" );
getterNames[1] = getter.getMethodName();
types[1] = getter.getReturnType();
setterNames[1] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "someInteger" );
setter = propertyAccessor.getSetter( Bean.class, "someInteger" );
getterNames[2] = getter.getMethodName();
types[2] = getter.getReturnType();
setterNames[2] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "someDate" );
setter = propertyAccessor.getSetter( Bean.class, "someDate" );
getterNames[3] = getter.getMethodName();
types[3] = getter.getReturnType();
setterNames[3] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "somelong" );
setter = propertyAccessor.getSetter( Bean.class, "somelong" );
getterNames[4] = getter.getMethodName();
types[4] = getter.getReturnType();
setterNames[4] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "someint" );
setter = propertyAccessor.getSetter( Bean.class, "someint" );
getterNames[5] = getter.getMethodName();
types[5] = getter.getReturnType();
setterNames[5] = setter.getMethodName();
getter = propertyAccessor.getGetter( Bean.class, "someObject" );
setter = propertyAccessor.getSetter( Bean.class, "someObject" );
getterNames[6] = getter.getMethodName();
types[6] = getter.getReturnType();
setterNames[6] = setter.getMethodName();
}
public static String[] getGetterNames() {
return getterNames;
}
public static String[] getSetterNames() {
return setterNames;
}
public static Class[] getTypes() {
return types;
}
}

View File

@ -0,0 +1,21 @@
package org.hibernate.test.bytecode;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* todo: describe BytecodeSuite
*
* @author Steve Ebersole
*/
public class BytecodeSuite {
public static Test suite() {
TestSuite suite = new TestSuite( "BytecodeProvider tests" );
suite.addTest( org.hibernate.test.bytecode.cglib.ReflectionOptimizerTest.suite() );
suite.addTest( org.hibernate.test.bytecode.cglib.InvocationTargetExceptionTest.suite() );
suite.addTest( org.hibernate.test.bytecode.cglib.CGLIBThreadLocalTest.suite() );
suite.addTest( org.hibernate.test.bytecode.javassist.ReflectionOptimizerTest.suite() );
suite.addTest( org.hibernate.test.bytecode.javassist.InvocationTargetExceptionTest.suite() );
return suite;
}
}

View File

@ -0,0 +1,31 @@
package org.hibernate.test.bytecode;
/**
* Created by IntelliJ IDEA.
* User: Paul
* Date: Mar 9, 2007
* Time: 11:31:40 AM
* To change this template use File | Settings | File Templates.
*/
public class ProxyBean {
private String someString;
private long someLong;
public String getSomeString() {
return someString;
}
public void setSomeString(String someString) {
this.someString = someString;
}
public long getSomeLong() {
return someLong;
}
public void setSomeLong(long someLong) {
this.someLong = someLong;
}
}

View File

@ -0,0 +1,73 @@
package org.hibernate.test.bytecode.cglib;
import org.hibernate.junit.functional.*;
import org.hibernate.cfg.*;
import org.hibernate.*;
import org.hibernate.proxy.*;
import org.hibernate.test.bytecode.*;
import junit.framework.*;
import java.text.*;
import java.lang.reflect.*;
import net.sf.cglib.proxy.*;
/**
* Test that the static thread local callback object is cleared out of the proxy class after instantiated.
* This tests that the memory leak reported by HHH-2481 hasn't been re-introduced.
*
* @author Paul Malolepsy
*/
public class CGLIBThreadLocalTest extends FunctionalTestCase {
public CGLIBThreadLocalTest(String name) {
super(name);
}
public String[] getMappings() {
return new String[]{"bytecode/Bean.hbm.xml"};
}
public static TestSuite suite() {
return new FunctionalTestClassTestSuite(CGLIBThreadLocalTest.class);
}
public void testCglibClearing() {
if (!(Environment.getBytecodeProvider() instanceof org.hibernate.bytecode.cglib.BytecodeProviderImpl)) {
// because of the scoping :(
reportSkip("env not configured for cglib provider", "cglib thread local callback clearing");
return;
}
//create the object for the test
Session s = openSession();
s.beginTransaction();
ProxyBean proxyBean = new ProxyBean();
proxyBean.setSomeString("my-bean");
proxyBean.setSomeLong(1234);
s.save(proxyBean);
s.getTransaction().commit();
s.close();
// read the object as a proxy
s = openSession();
s.beginTransaction();
proxyBean = (ProxyBean) s.load(ProxyBean.class, proxyBean.getSomeString());
assertTrue(proxyBean instanceof HibernateProxy);
try {
//check that the static thread callbacks thread local has been cleared out
Field field = proxyBean.getClass().getDeclaredField("CGLIB$THREAD_CALLBACKS");
field.setAccessible(true);
ThreadLocal threadCallbacksThreadLocal = (ThreadLocal) field.get(null);
assertTrue(threadCallbacksThreadLocal.get() == null);
} catch (NoSuchFieldException e1) {
fail("unable to find CGLIB$THREAD_CALLBACKS field in proxy.");
} catch (Throwable t) {
fail("unexpected exception type : " + t);
} finally {
//clean up
s.delete(proxyBean);
s.getTransaction().commit();
s.close();
}
}
}

View File

@ -0,0 +1,67 @@
package org.hibernate.test.bytecode.cglib;
import org.hibernate.test.TestCase;
import org.hibernate.test.bytecode.Bean;
import org.hibernate.Session;
import org.hibernate.Hibernate;
import org.hibernate.dialect.Dialect;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.cfg.Environment;
import junit.framework.TestSuite;
import java.text.ParseException;
/**
* Test that the Javassist-based lazy initializer properly handles
* InvocationTargetExceptions
*
* @author Steve Ebersole
*/
public class InvocationTargetExceptionTest extends FunctionalTestCase {
public InvocationTargetExceptionTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "bytecode/Bean.hbm.xml" };
}
public static TestSuite suite() {
return new FunctionalTestClassTestSuite( InvocationTargetExceptionTest.class );
}
public void testProxiedInvocationException() {
if ( ! ( Environment.getBytecodeProvider() instanceof org.hibernate.bytecode.cglib.BytecodeProviderImpl ) ) {
// because of the scoping :(
reportSkip( "env not configured for cglib provider", "bytecode-provider InvocationTargetException handling" );
return;
}
Session s = openSession();
s.beginTransaction();
Bean bean = new Bean();
bean.setSomeString( "my-bean" );
s.save( bean );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
bean = ( Bean ) s.load( Bean.class, bean.getSomeString() );
assertFalse( Hibernate.isInitialized( bean ) );
try {
bean.throwException();
fail( "exception not thrown" );
}
catch ( ParseException e ) {
// expected behavior
}
catch( Throwable t ) {
fail( "unexpected exception type : " + t );
}
s.delete( bean );
s.getTransaction().commit();
s.close();
}
}

View File

@ -0,0 +1,52 @@
package org.hibernate.test.bytecode.cglib;
import junit.framework.TestSuite;
import org.hibernate.bytecode.ReflectionOptimizer;
import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.test.bytecode.Bean;
import org.hibernate.test.bytecode.BeanReflectionHelper;
/**
* @author Steve Ebersole
*/
public class ReflectionOptimizerTest extends UnitTestCase {
public ReflectionOptimizerTest(String string) {
super( string );
}
public void testReflectionOptimization() {
BytecodeProviderImpl provider = new BytecodeProviderImpl();
ReflectionOptimizer optimizer = provider.getReflectionOptimizer(
Bean.class,
BeanReflectionHelper.getGetterNames(),
BeanReflectionHelper.getSetterNames(),
BeanReflectionHelper.getTypes()
);
assertNotNull( optimizer );
assertNotNull( optimizer.getInstantiationOptimizer() );
assertNotNull( optimizer.getAccessOptimizer() );
Object instance = optimizer.getInstantiationOptimizer().newInstance();
assertEquals( instance.getClass(), Bean.class );
Bean bean = ( Bean ) instance;
optimizer.getAccessOptimizer().setPropertyValues( bean, BeanReflectionHelper.TEST_VALUES );
assertEquals( bean.getSomeString(), BeanReflectionHelper.TEST_VALUES[0] );
Object[] values = optimizer.getAccessOptimizer().getPropertyValues( bean );
assertEquivalent( values, BeanReflectionHelper.TEST_VALUES );
}
private void assertEquivalent(Object[] checkValues, Object[] values) {
assertEquals( "Different lengths", checkValues.length, values.length );
for ( int i = 0; i < checkValues.length; i++ ) {
assertEquals( "different values at index [" + i + "]", checkValues[i], values[i] );
}
}
public static TestSuite suite() {
return new TestSuite( ReflectionOptimizerTest.class );
}
}

View File

@ -0,0 +1,68 @@
package org.hibernate.test.bytecode.javassist;
import java.text.ParseException;
import junit.framework.TestSuite;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.bytecode.Bean;
/**
* Test that the Javassist-based lazy initializer properly handles
* InvocationTargetExceptions
*
* @author Steve Ebersole
*/
public class InvocationTargetExceptionTest extends FunctionalTestCase {
public InvocationTargetExceptionTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "bytecode/Bean.hbm.xml" };
}
public static TestSuite suite() {
return new FunctionalTestClassTestSuite( InvocationTargetExceptionTest.class );
}
public void testProxiedInvocationException() {
if ( !( Environment.getBytecodeProvider() instanceof org.hibernate.bytecode.javassist.BytecodeProviderImpl ) ) {
// because of the scoping :(
reportSkip(
"env not configured for javassist provider", "bytecode-provider InvocationTargetException handling"
);
return;
}
Session s = openSession();
s.beginTransaction();
Bean bean = new Bean();
bean.setSomeString( "my-bean" );
s.save( bean );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
bean = ( Bean ) s.load( Bean.class, bean.getSomeString() );
assertFalse( Hibernate.isInitialized( bean ) );
try {
bean.throwException();
fail( "exception not thrown" );
}
catch ( ParseException e ) {
// expected behavior
}
catch ( Throwable t ) {
fail( "unexpected exception type : " + t );
}
s.delete( bean );
s.getTransaction().commit();
s.close();
}
}

View File

@ -0,0 +1,52 @@
package org.hibernate.test.bytecode.javassist;
import junit.framework.TestSuite;
import org.hibernate.bytecode.ReflectionOptimizer;
import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
import org.hibernate.junit.UnitTestCase;
import org.hibernate.test.bytecode.Bean;
import org.hibernate.test.bytecode.BeanReflectionHelper;
/**
* @author Steve Ebersole
*/
public class ReflectionOptimizerTest extends UnitTestCase {
public ReflectionOptimizerTest(String string) {
super( string );
}
public void testReflectionOptimization() {
BytecodeProviderImpl provider = new BytecodeProviderImpl();
ReflectionOptimizer optimizer = provider.getReflectionOptimizer(
Bean.class,
BeanReflectionHelper.getGetterNames(),
BeanReflectionHelper.getSetterNames(),
BeanReflectionHelper.getTypes()
);
assertNotNull( optimizer );
assertNotNull( optimizer.getInstantiationOptimizer() );
assertNotNull( optimizer.getAccessOptimizer() );
Object instance = optimizer.getInstantiationOptimizer().newInstance();
assertEquals( instance.getClass(), Bean.class );
Bean bean = ( Bean ) instance;
optimizer.getAccessOptimizer().setPropertyValues( bean, BeanReflectionHelper.TEST_VALUES );
assertEquals( bean.getSomeString(), BeanReflectionHelper.TEST_VALUES[0] );
Object[] values = optimizer.getAccessOptimizer().getPropertyValues( bean );
assertEquivalent( values, BeanReflectionHelper.TEST_VALUES );
}
private void assertEquivalent(Object[] checkValues, Object[] values) {
assertEquals( "Different lengths", checkValues.length, values.length );
for ( int i = 0; i < checkValues.length; i++ ) {
assertEquals( "different values at index [" + i + "]", checkValues[i], values[i] );
}
}
public static TestSuite suite() {
return new TestSuite( ReflectionOptimizerTest.class );
}
}

View File

@ -0,0 +1,217 @@
package org.hibernate.test.cache;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cache.ReadWriteCache;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
import org.hibernate.test.tm.DummyConnectionProvider;
import org.hibernate.test.tm.DummyTransactionManagerLookup;
import org.hibernate.transaction.JDBCTransactionFactory;
/**
* Common requirement testing for each {@link org.hibernate.cache.CacheProvider} impl.
*
* @author Steve Ebersole
*/
public abstract class BaseCacheProviderTestCase extends FunctionalTestCase {
// note that a lot of the fucntionality here is intended to be used
// in creating specific tests for each CacheProvider that would extend
// from a base test case (this) for common requirement testing...
public BaseCacheProviderTestCase(String x) {
super( x );
}
public String[] getMappings() {
return new String[] { "cache/Item.hbm.xml" };
}
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.CACHE_REGION_PREFIX, "" );
cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "true" );
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
cfg.setProperty( Environment.USE_STRUCTURED_CACHE, "true" );
cfg.setProperty( Environment.CACHE_PROVIDER, getCacheProvider().getName() );
if ( getConfigResourceKey() != null ) {
cfg.setProperty( getConfigResourceKey(), getConfigResourceLocation() );
}
if ( useTransactionManager() ) {
cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() );
}
else {
cfg.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() );
}
}
/**
* The cache provider to be tested.
*
* @return The cache provider.
*/
protected abstract Class getCacheProvider();
/**
* For provider-specific configuration, the name of the property key the
* provider expects.
*
* @return The provider-specific config key.
*/
protected abstract String getConfigResourceKey();
/**
* For provider-specific configuration, the resource location of that
* config resource.
*
* @return The config resource location.
*/
protected abstract String getConfigResourceLocation();
/**
* Should we use a transaction manager for transaction management.
*
* @return True if we should use a RM; false otherwise.
*/
protected abstract boolean useTransactionManager();
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();
SecondLevelCacheStatistics slcs = s.getSessionFactory().getStatistics()
.getSecondLevelCacheStatistics( Item.class.getName() );
assertEquals( slcs.getPutCount(), 1 );
assertEquals( slcs.getElementCountInMemory(), 1 );
assertEquals( slcs.getEntries().size(), 1 );
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();
assertEquals( slcs.getPutCount(), 2 );
Object entry = slcs.getEntries().get( i.getId() );
Map map;
if ( entry instanceof ReadWriteCache.Item ) {
map = new HashMap();
map = (Map) ( (ReadWriteCache.Item) entry ).getValue();
}
else {
map = (Map) entry;
}
assertTrue( map.get("description").equals("A bog standard item") );
assertTrue( map.get("name").equals("widget") );
// cleanup
s = openSession();
t = s.beginTransaction();
s.delete( i );
t.commit();
s.close();
}
public void testEmptySecondLevelCacheEntry() throws Exception {
getSessions().evictEntity( Item.class.getName() );
Statistics stats = getSessions().getStatistics();
stats.clear();
SecondLevelCacheStatistics statistics = stats.getSecondLevelCacheStatistics( Item.class.getName() );
Map cacheEntries = statistics.getEntries();
assertEquals( 0, cacheEntries.size() );
}
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();
Long initialVersion = item.getVersion();
// manually revert the version property
item.setVersion( new Long( item.getVersion().longValue() - 1 ) );
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 ) {
}
}
}
finally {
if ( s != null && s.isOpen() ) {
try {
s.close();
}
catch( Throwable ignore ) {
}
}
}
// check the version value in the cache...
SecondLevelCacheStatistics slcs = sfi().getStatistics()
.getSecondLevelCacheStatistics( VersionedItem.class.getName() );
Object entry = slcs.getEntries().get( item.getId() );
Long cachedVersionValue;
if ( entry instanceof ReadWriteCache.Lock ) {
//FIXME don't know what to test here
cachedVersionValue = new Long( ( (ReadWriteCache.Lock) entry).getUnlockTimestamp() );
}
else {
cachedVersionValue = ( Long ) ( (Map) entry ).get( "_version" );
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();
}
}

View File

@ -0,0 +1,21 @@
package org.hibernate.test.cache;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.test.cache.treecache.optimistic.OptimisticTreeCacheTest;
import org.hibernate.test.cache.treecache.pessimistic.TreeCacheTest;
import org.hibernate.test.cache.ehcache.EhCacheTest;
/**
* @author Steve Ebersole
*/
public class CacheSuite {
public static Test suite() {
TestSuite suite = new TestSuite( "CacheProvider tests");
suite.addTest( OptimisticTreeCacheTest.suite() );
suite.addTest( TreeCacheTest.suite() );
suite.addTest( EhCacheTest.suite() );
return suite;
}
}

26
test/org/hibernate/test/cache/Item.hbm.xml vendored Executable file
View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.cache">
<class name="Item" table="Items">
<id name="id">
<generator class="increment"/>
</id>
<property name="name" not-null="true"/>
<property name="description" not-null="true"/>
</class>
<class name="VersionedItem" table="VersionedItems">
<id name="id">
<generator class="increment"/>
</id>
<version name="version" type="long"/>
<property name="name" not-null="true"/>
<property name="description" not-null="true"/>
</class>
</hibernate-mapping>

31
test/org/hibernate/test/cache/Item.java vendored Executable file
View File

@ -0,0 +1,31 @@
//$Id$
package org.hibernate.test.cache;
/**
* @author Gavin King
*/
public class Item {
private Long id;
private String name;
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,16 @@
package org.hibernate.test.cache;
/**
* @author Steve Ebersole
*/
public class VersionedItem extends Item {
private Long version;
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}

View File

@ -0,0 +1,48 @@
//$Id: $
package org.hibernate.test.cache.ehcache;
import junit.framework.Test;
import org.hibernate.cache.EhCacheProvider;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.cache.BaseCacheProviderTestCase;
/**
* @author Emmanuel Bernard
*/
public class EhCacheTest extends BaseCacheProviderTestCase {
// note that a lot of the fucntionality here is intended to be used
// in creating specific tests for each CacheProvider that would extend
// from a base test case (this) for common requirement testing...
public EhCacheTest(String x) {
super( x );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( EhCacheTest.class );
}
public String getCacheConcurrencyStrategy() {
return "read-write";
}
protected Class getCacheProvider() {
return EhCacheProvider.class;
}
protected String getConfigResourceKey() {
return Environment.CACHE_PROVIDER_CONFIG;
}
protected String getConfigResourceLocation() {
return "org/hibernate/test/cache/ehcache/ehcache.xml";
}
protected boolean useTransactionManager() {
return false;
}
}

View File

@ -0,0 +1,88 @@
<ehcache>
<!-- Sets the path to the directory where cache .data files are created.
If the path is a Java System Property it is replaced by
its value in the running VM.
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir"/>
<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.
The following attributes are required for defaultCache:
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<!--Predefined caches. Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts
The following attributes are required for defaultCache:
name - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.
-->
<!-- Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes.
If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
-->
<cache name="sampleCache1"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>
<!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<cache name="sampleCache2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> -->
<!-- Place configuration for your caches following -->
</ehcache>

View File

@ -0,0 +1,112 @@
package org.hibernate.test.cache.treecache.optimistic;
import junit.framework.Test;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.config.Option;
import org.jboss.cache.optimistic.DataVersion;
import org.hibernate.cache.OptimisticTreeCacheProvider;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.cache.BaseCacheProviderTestCase;
import org.hibernate.test.tm.DummyTransactionManager;
/**
* @author Steve Ebersole
*/
public class OptimisticTreeCacheTest extends BaseCacheProviderTestCase {
// note that a lot of the fucntionality here is intended to be used
// in creating specific tests for each CacheProvider that would extend
// from a base test case (this) for common requirement testing...
public OptimisticTreeCacheTest(String x) {
super( x );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( OptimisticTreeCacheTest.class );
}
public String getCacheConcurrencyStrategy() {
return "transactional";
}
protected Class getCacheProvider() {
return OptimisticTreeCacheProvider.class;
}
protected String getConfigResourceKey() {
return Environment.CACHE_PROVIDER_CONFIG;
}
protected String getConfigResourceLocation() {
return "org/hibernate/test/cache/treecache/optimistic/treecache.xml";
}
protected boolean useTransactionManager() {
return true;
}
public void testCacheLevelStaleWritesFail() throws Throwable {
Fqn fqn = new Fqn( "whatever" );
TreeCache treeCache = ( ( OptimisticTreeCacheProvider ) sfi().getSettings().getCacheProvider() ).getUnderlyingCache();
Long long1 = new Long(1);
Long long2 = new Long(2);
try {
System.out.println( "****************************************************************" );
DummyTransactionManager.INSTANCE.begin();
treeCache.put( fqn, "ITEM", long1, ManualDataVersion.gen( 1 ) );
DummyTransactionManager.INSTANCE.commit();
System.out.println( "****************************************************************" );
DummyTransactionManager.INSTANCE.begin();
treeCache.put( fqn, "ITEM", long2, ManualDataVersion.gen( 2 ) );
DummyTransactionManager.INSTANCE.commit();
try {
System.out.println( "****************************************************************" );
DummyTransactionManager.INSTANCE.begin();
treeCache.put( fqn, "ITEM", long1, ManualDataVersion.gen( 1 ) );
DummyTransactionManager.INSTANCE.commit();
fail( "stale write allowed" );
}
catch( Throwable ignore ) {
// expected behavior
DummyTransactionManager.INSTANCE.rollback();
}
Long current = ( Long ) treeCache.get( fqn, "ITEM" );
assertEquals( "unexpected current value", 2, current.longValue() );
}
finally {
try {
treeCache.remove( fqn, "ITEM" );
}
catch( Throwable ignore ) {
}
}
}
private static class ManualDataVersion implements DataVersion {
private final int version;
public ManualDataVersion(int version) {
this.version = version;
}
public boolean newerThan(DataVersion dataVersion) {
return this.version > ( ( ManualDataVersion ) dataVersion ).version;
}
public static Option gen(int version) {
ManualDataVersion mdv = new ManualDataVersion( version );
Option option = new Option();
option.setDataVersion( mdv );
return option;
}
}
}

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- Sample TreeCache Service Configuration -->
<!-- Recommended for use as Hibernate's 2nd Level Cache -->
<!-- For use with JBossCache >= 1.3.0 ONLY!!! -->
<!-- -->
<!-- ===================================================================== -->
<server>
<classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar"/>
<!-- ==================================================================== -->
<!-- Defines TreeCache configuration -->
<!-- ==================================================================== -->
<mbean code="org.jboss.cache.TreeCache"
name="jboss.cache:service=TreeCache">
<depends>jboss:service=Naming</depends>
<depends>jboss:service=TransactionManager</depends>
<!--
Configure the TransactionManager : no matter since Hibernate will plug in
an "adapter" to its own TransactionManagerLookup strategy here
-->
<attribute name="TransactionManagerLookupClass">org.jboss.cache.GenericTransactionManagerLookup</attribute>
<!--
Node locking scheme:
OPTIMISTIC
PESSIMISTIC (default)
-->
<attribute name="NodeLockingScheme">OPTIMISTIC</attribute>
<!--
Note that this attribute is IGNORED if your NodeLockingScheme above is OPTIMISTIC.
Isolation level : SERIALIZABLE
REPEATABLE_READ (default)
READ_COMMITTED
READ_UNCOMMITTED
NONE
-->
<attribute name="IsolationLevel">REPEATABLE_READ</attribute>
<!--
Valid modes are LOCAL
REPL_ASYNC
REPL_SYNC
INVALIDATION_ASYNC
INVALIDATION_SYNC
INVALIDATION_ASYNC is highly recommended as the mode for use
with clustered second-level caches.
-->
<attribute name="CacheMode">LOCAL</attribute>
<!--
Just used for async repl: use a replication queue
-->
<attribute name="UseReplQueue">false</attribute>
<!--
Replication interval for replication queue (in ms)
-->
<attribute name="ReplQueueInterval">0</attribute>
<!--
Max number of elements which trigger replication
-->
<attribute name="ReplQueueMaxElements">0</attribute>
<!-- Name of cluster. Needs to be the same for all clusters, in order
to find each other
-->
<attribute name="ClusterName">TreeCache-Cluster</attribute>
<!-- JGroups protocol stack properties. Can also be a URL,
e.g. file:/home/bela/default.xml
<attribute name="ClusterProperties"></attribute>
-->
<attribute name="ClusterConfig">
<config>
<!-- UDP: if you have a multihomed machine,
set the bind_addr attribute to the appropriate NIC IP address -->
<!-- UDP: On Windows machines, because of the media sense feature
being broken with multicast (even after disabling media sense)
set the loopback attribute to true -->
<UDP mcast_addr="228.1.2.3" mcast_port="48866"
ip_ttl="64" ip_mcast="true"
mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
loopback="false"/>
<PING timeout="2000" num_initial_members="3"
up_thread="false" down_thread="false"/>
<MERGE2 min_interval="10000" max_interval="20000"/>
<!-- <FD shun="true" up_thread="true" down_thread="true" />-->
<FD_SOCK/>
<VERIFY_SUSPECT timeout="1500"
up_thread="false" down_thread="false"/>
<pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800"
max_xmit_size="8192" up_thread="false" down_thread="false"/>
<UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10"
down_thread="false"/>
<pbcast.STABLE desired_avg_gossip="20000"
up_thread="false" down_thread="false"/>
<FRAG frag_size="8192"
down_thread="false" up_thread="false"/>
<pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
shun="true" print_local_addr="true"/>
<pbcast.STATE_TRANSFER up_thread="true" down_thread="true"/>
</config>
</attribute>
<!--
Whether or not to fetch state on joining a cluster
NOTE this used to be called FetchStateOnStartup and has been renamed to be more descriptive.
-->
<attribute name="FetchInMemoryState">false</attribute>
<!--
Number of milliseconds to wait until all responses for a
synchronous call have been received.
-->
<attribute name="SyncReplTimeout">20000</attribute>
<!-- Max number of milliseconds to wait for a lock acquisition -->
<attribute name="LockAcquisitionTimeout">15000</attribute>
<!-- Name of the eviction policy class. -->
<attribute name="EvictionPolicyClass"></attribute>
<!--
Indicate whether to use marshalling or not. Set this to true if you are running under a scoped
class loader, e.g., inside an application server. Default is "false".
-->
<attribute name="UseMarshalling">false</attribute>
</mbean>
</server>

View File

@ -0,0 +1,47 @@
package org.hibernate.test.cache.treecache.pessimistic;
import junit.framework.Test;
import org.hibernate.cache.TreeCacheProvider;
import org.hibernate.cfg.Environment;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
import org.hibernate.test.cache.BaseCacheProviderTestCase;
/**
* @author Steve Ebersole
*/
public class TreeCacheTest extends BaseCacheProviderTestCase {
// note that a lot of the fucntionality here is intended to be used
// in creating specific tests for each CacheProvider that would extend
// from a base test case (this) for common requirement testing...
public TreeCacheTest(String x) {
super( x );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( TreeCacheTest.class );
}
public String getCacheConcurrencyStrategy() {
return "transactional";
}
protected Class getCacheProvider() {
return TreeCacheProvider.class;
}
protected String getConfigResourceKey() {
return Environment.CACHE_PROVIDER_CONFIG;
}
protected String getConfigResourceLocation() {
return "org/hibernate/test/cache/treecache/pessimistic/treecache.xml";
}
protected boolean useTransactionManager() {
return true;
}
}

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- -->
<!-- Sample TreeCache Service Configuration -->
<!-- -->
<!-- ===================================================================== -->
<server>
<classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar"/>
<!-- ==================================================================== -->
<!-- Defines TreeCache configuration -->
<!-- ==================================================================== -->
<mbean code="org.jboss.cache.TreeCache"
name="jboss.cache:service=TreeCache">
<depends>jboss:service=Naming</depends>
<depends>jboss:service=TransactionManager</depends>
<!--
TransactionManager configuration not required for Hibernate!
-->
<!--
Node isolation level : SERIALIZABLE
REPEATABLE_READ (default)
READ_COMMITTED
READ_UNCOMMITTED
NONE
-->
<attribute name="IsolationLevel">REPEATABLE_READ</attribute>
<!--
Valid modes are LOCAL
REPL_ASYNC
REPL_SYNC
-->
<attribute name="CacheMode">LOCAL</attribute>
<!-- Name of cluster. Needs to be the same for all clusters, in order
to find each other
-->
<attribute name="ClusterName">TreeCache-Cluster</attribute>
<!-- JGroups protocol stack properties. Can also be a URL,
e.g. file:/home/bela/default.xml
<attribute name="ClusterProperties"></attribute>
-->
<attribute name="ClusterConfig">
<config>
<!-- UDP: if you have a multihomed machine,
set the bind_addr attribute to the appropriate NIC IP address -->
<!-- UDP: On Windows machines, because of the media sense feature
being broken with multicast (even after disabling media sense)
set the loopback attribute to true -->
<UDP mcast_addr="228.1.2.3" mcast_port="45566"
ip_ttl="64" ip_mcast="true"
mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
loopback="false"/>
<PING timeout="2000" num_initial_members="3"
up_thread="false" down_thread="false"/>
<MERGE2 min_interval="10000" max_interval="20000"/>
<FD shun="true" up_thread="true" down_thread="true"/>
<VERIFY_SUSPECT timeout="1500"
up_thread="false" down_thread="false"/>
<pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800"
up_thread="false" down_thread="false"/>
<pbcast.STABLE desired_avg_gossip="20000"
up_thread="false" down_thread="false"/>
<UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10"
down_thread="false"/>
<FRAG frag_size="8192"
down_thread="false" up_thread="false"/>
<pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
shun="true" print_local_addr="true"/>
<pbcast.STATE_TRANSFER up_thread="false" down_thread="false"/>
</config>
</attribute>
<!--
Max number of entries in the cache. If this is exceeded, the
eviction policy will kick some entries out in order to make
more room
-->
<attribute name="MaxCapacity">20000</attribute>
<!--
The max amount of time (in milliseconds) we wait until the
initial state (ie. the contents of the cache) are retrieved from
existing members in a clustered environment
-->
<attribute name="InitialStateRetrievalTimeout">20000</attribute>
<!--
Number of milliseconds to wait until all responses for a
synchronous call have been received.
-->
<attribute name="SyncReplTimeout">10000</attribute>
<!-- Max number of milliseconds to wait for a lock acquisition -->
<attribute name="LockAcquisitionTimeout">15000</attribute>
<!-- Max number of milliseconds we hold a lock (not currently
implemented) -->
<attribute name="LockLeaseTimeout">60000</attribute>
<!-- Name of the eviction policy class. Not supported now. -->
<attribute name="EvictionPolicyClass"></attribute>
</mbean>
</server>

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.test.cascade">
<class name="Job" table="T_JOB">
<id name="id" column="JOB_ID">
<generator class="native"/>
</id>
<many-to-one name="batch" class="JobBatch" cascade="none" column="BATCH_ID"/>
<property name="status" type="int" column="JOB_STATUS" not-null="true"/>
<property name="processingInstructions" type="string" column="PI" not-null="true"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,53 @@
// $Id$
package org.hibernate.test.cascade;
/**
* Implementation of Job.
*
* @author Steve Ebersole
*/
public class Job {
private Long id;
private JobBatch batch;
private String processingInstructions;
private int status;
/** GCLIB constructor */
Job() {}
protected Job(JobBatch batch) {
this.batch = batch;
}
public Long getId() {
return id;
}
/*package*/ void setId(Long id) {
this.id = id;
}
public JobBatch getBatch() {
return batch;
}
/*package*/ void setBatch(JobBatch batch) {
this.batch = batch;
}
public String getProcessingInstructions() {
return processingInstructions;
}
public void setProcessingInstructions(String processingInstructions) {
this.processingInstructions = processingInstructions;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.test.cascade">
<class name="JobBatch" table="T_JOB_BATCH">
<id name="id" column="BATCH_ID">
<generator class="native"/>
</id>
<property name="batchDate" type="timestamp" column="BATCH_DATE" not-null="true"/>
<set name="jobs" inverse="true" fetch="select" lazy="true" cascade="all, refresh">
<key column="BATCH_ID"/>
<one-to-many class="Job"/>
</set>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,54 @@
// $Id$
package org.hibernate.test.cascade;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
/**
* Implementation of JobBatch.
*
* @author Steve Ebersole
*/
public class JobBatch {
private Long id;
private Date batchDate;
private Set jobs = new HashSet();
/** CGLIB constructor */
JobBatch() {}
public JobBatch(Date batchDate) {
this.batchDate = batchDate;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getBatchDate() {
return batchDate;
}
public void setBatchDate(Date batchDate) {
this.batchDate = batchDate;
}
public Set getJobs() {
return jobs;
}
public void setJobs(Set jobs) {
this.jobs = jobs;
}
public Job createJob() {
Job job = new Job( this );
jobs.add( job );
return job;
}
}

View File

@ -0,0 +1,79 @@
// $Id$
package org.hibernate.test.cascade;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Date;
import java.util.Iterator;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* Implementation of RefreshTest.
*
* @author Steve Ebersole
*/
public class RefreshTest extends FunctionalTestCase {
public RefreshTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "cascade/Job.hbm.xml", "cascade/JobBatch.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( RefreshTest.class );
}
public void testRefreshCascade() throws Throwable {
Session session = openSession();
Transaction txn = session.beginTransaction();
JobBatch batch = new JobBatch( new Date() );
batch.createJob().setProcessingInstructions( "Just do it!" );
batch.createJob().setProcessingInstructions( "I know you can do it!" );
// write the stuff to the database; at this stage all job.status values are zero
session.persist( batch );
session.flush();
// behind the session's back, let's modify the statuses
updateStatuses( session.connection() );
// Now lets refresh the persistent batch, and see if the refresh cascaded to the jobs collection elements
session.refresh( batch );
Iterator itr = batch.getJobs().iterator();
while( itr.hasNext() ) {
Job job = ( Job ) itr.next();
assertEquals( "Jobs not refreshed!", 1, job.getStatus() );
}
txn.rollback();
session.close();
}
private void updateStatuses(Connection connection) throws Throwable {
PreparedStatement stmnt = null;
try {
stmnt = connection.prepareStatement( "UPDATE T_JOB SET JOB_STATUS = 1" );
stmnt.executeUpdate();
}
finally {
if ( stmnt != null ) {
try {
stmnt.close();
}
catch( Throwable ignore ) {
}
}
}
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class entity-name="Entity">
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,44 @@
package org.hibernate.test.cfg;
import java.io.File;
import org.hibernate.cfg.Configuration;
import org.hibernate.junit.UnitTestCase;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class CacheableFileTest extends UnitTestCase {
public static final String MAPPING = "org/hibernate/test/cfg/Cacheable.hbm.xml";
private File mappingFile;
public CacheableFileTest(String string) {
super( string );
}
protected void setUp() throws Exception {
super.setUp();
mappingFile = new File( getClass().getClassLoader().getResource( MAPPING ).getFile() );
assertTrue( mappingFile.exists() );
File cached = new File( mappingFile.getParentFile(), mappingFile.getName() + ".bin" );
if ( cached.exists() ) {
cached.delete();
}
}
protected void tearDown() throws Exception {
mappingFile = null;
super.tearDown();
}
public void testCachedFiles() {
Configuration cfg = new Configuration();
cfg.addCacheableFile( mappingFile );
Configuration cfg2 = new Configuration();
cfg2.addCacheableFile( mappingFile );
}
}

View File

@ -0,0 +1,269 @@
//$Id$
package org.hibernate.test.cid;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* @author Gavin King
*/
public class CompositeIdTest extends FunctionalTestCase {
public CompositeIdTest(String str) {
super(str);
}
public String[] getMappings() {
return new String[] { "cid/Customer.hbm.xml", "cid/Order.hbm.xml", "cid/LineItem.hbm.xml", "cid/Product.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite(CompositeIdTest.class);
}
public void testQuery() {
Session s = openSession();
Transaction t = s.beginTransaction();
s.createQuery("from LineItem ol where ol.order.id.customerId = 'C111'").list();
t.commit();
s.close();
}
public void testCompositeIds() {
Session s = openSession();
Transaction t = s.beginTransaction();
Product p = new Product();
p.setProductId("A123");
p.setDescription("nipple ring");
p.setPrice( new BigDecimal(1.0) );
p.setNumberAvailable(1004);
s.persist(p);
Product p2 = new Product();
p2.setProductId("X525");
p2.setDescription("nose stud");
p2.setPrice( new BigDecimal(3.0) );
p2.setNumberAvailable(105);
s.persist(p2);
Customer c = new Customer();
c.setAddress("St Kilda Rd, MEL, 3000");
c.setName("Virginia");
c.setCustomerId("C111");
s.persist(c);
Order o = new Order(c);
o.setOrderDate( Calendar.getInstance() );
LineItem li = new LineItem(o, p);
li.setQuantity(2);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
o = (Order) s.get( Order.class, new Order.Id("C111", 0) );
assertEquals( o.getTotal().intValue(), 2 );
o.getCustomer().getName();
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
s.createQuery("from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p").list();
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
s.createQuery("from Order o left join fetch o.lineItems li left join fetch li.product p").list();
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
Iterator iter = s.createQuery("select o.id, li.id from Order o join o.lineItems li").list().iterator();
while ( iter.hasNext() ) {
Object[] stuff = (Object[]) iter.next();
assertTrue(stuff.length==2);
}
iter = s.createQuery("from Order o join o.lineItems li").iterate();
while ( iter.hasNext() ) {
Object[] stuff = (Object[]) iter.next();
assertTrue(stuff.length==2);
}
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
c = (Customer) s.get( Customer.class, "C111" );
Order o2 = new Order(c);
o2.setOrderDate( Calendar.getInstance() );
s.flush();
LineItem li2 = new LineItem(o2, p2);
li2.setQuantity(5);
List bigOrders = s.createQuery("from Order o where o.total>10.0").list();
assertEquals( bigOrders.size(), 1 );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
s.createQuery("delete from LineItem").executeUpdate();
s.createQuery("delete from Order").executeUpdate();
s.createQuery("delete from Customer").executeUpdate();
s.createQuery("delete from Product").executeUpdate();
t.commit();
s.close();
}
public void testNonLazyFetch() {
Session s = openSession();
Transaction t = s.beginTransaction();
Product p = new Product();
p.setProductId("A123");
p.setDescription("nipple ring");
p.setPrice( new BigDecimal(1.0) );
p.setNumberAvailable(1004);
s.persist(p);
Product p2 = new Product();
p2.setProductId("X525");
p2.setDescription("nose stud");
p2.setPrice( new BigDecimal(3.0) );
p2.setNumberAvailable(105);
s.persist(p2);
Customer c = new Customer();
c.setAddress("St Kilda Rd, MEL, 3000");
c.setName("Virginia");
c.setCustomerId("C111");
s.persist(c);
Order o = new Order(c);
o.setOrderDate( Calendar.getInstance() );
LineItem li = new LineItem(o, p);
li.setQuantity(2);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
o = (Order) s.get( Order.class, new Order.Id("C111", 0) );
assertEquals( o.getTotal().intValue(), 2 );
o.getCustomer().getName();
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
o = (Order) s.createQuery("from Order o left join fetch o.lineItems li left join fetch li.product p").uniqueResult();
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
li = (LineItem) o.getLineItems().iterator().next();
assertTrue( Hibernate.isInitialized( li ) );
assertTrue( Hibernate.isInitialized( li.getProduct() ) );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
o = (Order) s.createQuery("from Order o").uniqueResult();
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
li = (LineItem) o.getLineItems().iterator().next();
assertTrue( Hibernate.isInitialized( li ) );
assertFalse( Hibernate.isInitialized( li.getProduct() ) );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
s.createQuery("delete from LineItem").executeUpdate();
s.createQuery("delete from Order").executeUpdate();
s.createQuery("delete from Customer").executeUpdate();
s.createQuery("delete from Product").executeUpdate();
t.commit();
s.close();
}
public void testMultipleCollectionFetch() {
Session s = openSession();
Transaction t = s.beginTransaction();
Product p = new Product();
p.setProductId("A123");
p.setDescription("nipple ring");
p.setPrice( new BigDecimal(1.0) );
p.setNumberAvailable(1004);
s.persist(p);
Product p2 = new Product();
p2.setProductId("X525");
p2.setDescription("nose stud");
p2.setPrice( new BigDecimal(3.0) );
p2.setNumberAvailable(105);
s.persist(p2);
Customer c = new Customer();
c.setAddress("St Kilda Rd, MEL, 3000");
c.setName("Virginia");
c.setCustomerId("C111");
s.persist(c);
Order o = new Order(c);
o.setOrderDate( Calendar.getInstance() );
LineItem li = new LineItem(o, p);
li.setQuantity(2);
LineItem li2 = new LineItem(o, p2);
li2.setQuantity(3);
Order o2 = new Order(c);
o2.setOrderDate( Calendar.getInstance() );
LineItem li3 = new LineItem(o2, p);
li3.setQuantity(1);
LineItem li4 = new LineItem(o2, p2);
li4.setQuantity(1);
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
c = (Customer) s.createQuery("from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p").uniqueResult();
assertTrue( Hibernate.isInitialized( c.getOrders() ) );
assertEquals( c.getOrders().size(), 2 );
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get(0) ).getLineItems() ) );
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get(1) ).getLineItems() ) );
assertEquals( ( (Order) c.getOrders().get(0) ).getLineItems().size(), 2 );
assertEquals( ( (Order) c.getOrders().get(1) ).getLineItems().size(), 2 );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
s.createQuery("delete from LineItem").executeUpdate();
s.createQuery("delete from Order").executeUpdate();
s.createQuery("delete from Customer").executeUpdate();
s.createQuery("delete from Product").executeUpdate();
t.commit();
s.close();
}
}

View File

@ -0,0 +1,37 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
This mapping demonstrates how to map a collection
<key> to one of the primary key columns of an
associated child class with a composite key. This
is very useful for legacy data!
-->
<hibernate-mapping package="org.hibernate.test.cid">
<class name="Customer">
<id name="customerId"
length="10">
<generator class="assigned"/>
</id>
<property name="name" not-null="true" length="100"/>
<property name="address" not-null="true" length="200"/>
<list name="orders"
inverse="true"
cascade="save-update">
<key column="customerId"/>
<index column="orderNumber"/>
<one-to-many class="Order"/>
</list>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,73 @@
//$Id$
package org.hibernate.test.cid;
import java.util.ArrayList;
import java.util.List;
import java.util.GregorianCalendar;
import java.math.BigDecimal;
/**
* @author Gavin King
*/
public class Customer {
private String customerId;
private String name;
private String address;
private List orders = new ArrayList();
/**
* @return Returns the address.
*/
public String getAddress() {
return address;
}
/**
* @param address The address to set.
*/
public void setAddress(String address) {
this.address = address;
}
/**
* @return Returns the customerId.
*/
public String getCustomerId() {
return customerId;
}
/**
* @param customerId The customerId to set.
*/
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* @return Returns the orders.
*/
public List getOrders() {
return orders;
}
/**
* @param orders The orders to set.
*/
public void setOrders(List orders) {
this.orders = orders;
}
public Order generateNewOrder(BigDecimal total) {
Order order = new Order(this);
order.setOrderDate( new GregorianCalendar() );
order.setTotal( total );
return order;
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
This mapping demonstrates
(1) composite keys and many-to-one associations on
composite keys
(2) use of insert="false" update="false" on an
association mapping, when the foreign key is
also part of the primary key
-->
<hibernate-mapping package="org.hibernate.test.cid">
<class name="LineItem">
<composite-id name="id"
class="LineItem$Id">
<key-property name="customerId" length="10"/>
<key-property name="orderNumber"/>
<key-property name="productId" length="10"/>
</composite-id>
<property name="quantity"/>
<many-to-one name="order"
insert="false"
update="false"
not-null="true">
<column name="customerId"/>
<column name="orderNumber"/>
</many-to-one>
<many-to-one name="product"
insert="false"
update="false"
not-null="true"
column="productId"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,137 @@
//$Id$
package org.hibernate.test.cid;
import java.io.Serializable;
/**
* @author Gavin King
*/
public class LineItem {
public static class Id implements Serializable {
private String customerId;
private int orderNumber;
private String productId;
public Id(String customerId, int orderNumber, String productId) {
this.customerId = customerId;
this.orderNumber = orderNumber;
this.productId = productId;
}
public Id() {}
/**
* @return Returns the customerId.
*/
public String getCustomerId() {
return customerId;
}
/**
* @param customerId The customerId to set.
*/
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
/**
* @return Returns the productId.
*/
public String getProductId() {
return productId;
}
/**
* @param productId The productId to set.
*/
public void setProductId(String productId) {
this.productId = productId;
}
/**
* @return Returns the orderNumber.
*/
public int getOrderNumber() {
return orderNumber;
}
/**
* @param orderNumber The orderNumber to set.
*/
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public int hashCode() {
return customerId.hashCode() + orderNumber + productId.hashCode();
}
public boolean equals(Object other) {
if (other instanceof Id) {
Id that = (Id) other;
return that.customerId.equals(this.customerId) &&
that.productId.equals(this.productId) &&
that.orderNumber == this.orderNumber;
}
else {
return false;
}
}
}
private Id id = new Id();
private int quantity;
private Order order;
private Product product;
public LineItem(Order o, Product p) {
this.order = o;
this.id.orderNumber = o.getId().getOrderNumber();
this.id.customerId = o.getId().getCustomerId();
this.id.productId = p.getProductId();
o.getLineItems().add(this);
}
public LineItem() {}
/**
* @return Returns the order.
*/
public Order getOrder() {
return order;
}
/**
* @param order The order to set.
*/
public void setOrder(Order order) {
this.order = order;
}
/**
* @return Returns the product.
*/
public Product getProduct() {
return product;
}
/**
* @param product The product to set.
*/
public void setProduct(Product product) {
this.product = product;
}
/**
* @return Returns the quantity.
*/
public int getQuantity() {
return quantity;
}
/**
* @param quantity The quantity to set.
*/
public void setQuantity(int quantity) {
this.quantity = quantity;
}
/**
* @return Returns the id.
*/
public Id getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(Id id) {
this.id = id;
}
}

View File

@ -0,0 +1,66 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.cid">
<!--
This mapping demonstrates
(1) composite keys and one-to-many associations on
composite keys
(2) use of insert="false" update="false" on an
association mapping, when the foreign key is
also part of the primary key
(3) use of a derived property which performs a
subselect against associated tables
(4) use of <synchronize/> to ensure that auto-flush
works correctly for an entity with a property
derived from other tables
-->
<class name="Order" table="CustomerOrder">
<synchronize table="LineItem"/>
<synchronize table="Product"/>
<composite-id name="id"
class="Order$Id">
<key-property name="customerId" length="10"/>
<key-property name="orderNumber"/>
</composite-id>
<property name="orderDate"
type="calendar_date"
not-null="true"/>
<property name="total"
formula="( select sum(li.quantity*p.cost) from LineItem li, Product p where li.productId = p.productId and li.customerId = customerId and li.orderNumber = orderNumber )"/>
<many-to-one name="customer"
column="customerId"
insert="false"
update="false"
not-null="true"/>
<bag name="lineItems"
fetch="join"
lazy="false"
inverse="true"
cascade="save-update">
<key>
<column name="customerId"/>
<column name="orderNumber"/>
</key>
<one-to-many class="LineItem"/>
</bag>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,145 @@
//$Id$
package org.hibernate.test.cid;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
/**
* @author Gavin King
*/
public class Order {
public static class Id implements Serializable {
private String customerId;
private int orderNumber;
public Id(String customerId, int orderNumber) {
this.customerId = customerId;
this.orderNumber = orderNumber;
}
public Id() {}
/**
* @return Returns the customerId.
*/
public String getCustomerId() {
return customerId;
}
/**
* @param customerId The customerId to set.
*/
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
/**
* @return Returns the orderNumber.
*/
public int getOrderNumber() {
return orderNumber;
}
/**
* @param orderNumber The orderNumber to set.
*/
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public int hashCode() {
return customerId.hashCode() + orderNumber;
}
public boolean equals(Object other) {
if (other instanceof Id) {
Id that = (Id) other;
return that.customerId.equals(this.customerId) &&
that.orderNumber == this.orderNumber;
}
else {
return false;
}
}
}
private Id id = new Id();
private Calendar orderDate;
private Customer customer;
private Collection lineItems = new ArrayList();
private BigDecimal total;
public Order(Customer customer) {
this.customer = customer;
this.id.customerId = customer.getCustomerId();
this.id.orderNumber = customer.getOrders().size();
customer.getOrders().add(this);
}
public Order() {}
/**
* @return Returns the customer.
*/
public Customer getCustomer() {
return customer;
}
/**
* @param customer The customer to set.
*/
public void setCustomer(Customer customer) {
this.customer = customer;
}
/**
* @return Returns the lineItems.
*/
public Collection getLineItems() {
return lineItems;
}
/**
* @param lineItems The lineItems to set.
*/
public void setLineItems(Collection lineItems) {
this.lineItems = lineItems;
}
/**
* @return Returns the orderDate.
*/
public Calendar getOrderDate() {
return orderDate;
}
/**
* @param orderDate The orderDate to set.
*/
public void setOrderDate(Calendar orderDate) {
this.orderDate = orderDate;
}
/**
* @return Returns the total.
*/
public BigDecimal getTotal() {
return total;
}
/**
* @param total The total to set.
*/
public void setTotal(BigDecimal total) {
this.total = total;
}
/**
* @return Returns the id.
*/
public Id getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(Id id) {
this.id = id;
}
public LineItem generateLineItem( Product product, int quantity ) {
LineItem li = new LineItem( this, product );
li.setQuantity( quantity );
lineItems.add( li );
return li;
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.cid">
<!--
This mapping demonstrates
(1) use of a derived property which performs a
subselect against an associated table
(2) use of <synchronize/> to ensure that auto-flush
works correctly for an entity with a property
derived from another table
-->
<class name="Product">
<synchronize table="LineItem"/>
<id name="productId"
length="10">
<generator class="assigned"/>
</id>
<property name="description"
not-null="true"
length="200"/>
<property name="price" length="3" column="cost"/>
<property name="numberAvailable"/>
<property name="numberOrdered"
formula="( select sum(li.quantity) from LineItem li where li.productId = productId )"/>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,75 @@
//$Id$
package org.hibernate.test.cid;
import java.math.BigDecimal;
/**
* @author Gavin King
*/
public class Product {
private String productId;
private String description;
private BigDecimal price;
private int numberAvailable;
private int numberOrdered;
/**
* @return Returns the description.
*/
public String getDescription() {
return description;
}
/**
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* @return Returns the numberAvailable.
*/
public int getNumberAvailable() {
return numberAvailable;
}
/**
* @param numberAvailable The numberAvailable to set.
*/
public void setNumberAvailable(int numberAvailable) {
this.numberAvailable = numberAvailable;
}
/**
* @return Returns the numberOrdered.
*/
public int getNumberOrdered() {
return numberOrdered;
}
/**
* @param numberOrdered The numberOrdered to set.
*/
public void setNumberOrdered(int numberOrdered) {
this.numberOrdered = numberOrdered;
}
/**
* @return Returns the productId.
*/
public String getProductId() {
return productId;
}
/**
* @param productId The productId to set.
*/
public void setProductId(String productId) {
this.productId = productId;
}
/**
* @return Returns the price.
*/
public BigDecimal getPrice() {
return price;
}
/**
* @param price The price to set.
*/
public void setPrice(BigDecimal price) {
this.price = price;
}
}

View File

@ -0,0 +1,31 @@
package org.hibernate.test.collection;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.hibernate.test.collection.bag.PersistentBagTest;
import org.hibernate.test.collection.idbag.PersistentIdBagTest;
import org.hibernate.test.collection.list.PersistentListTest;
import org.hibernate.test.collection.map.PersistentMapTest;
import org.hibernate.test.collection.original.CollectionTest;
import org.hibernate.test.collection.set.PersistentSetTest;
/**
* Suite of collection (i.e. PersistentCollection) related tests
*
* @author Steve Ebersole
*/
public class CollectionSuite {
public static Test suite() {
TestSuite suite = new TestSuite( "Collection-related tests" );
suite.addTest( PersistentBagTest.suite() );
suite.addTest( PersistentIdBagTest.suite() );
suite.addTest( PersistentListTest.suite() );
suite.addTest( PersistentMapTest.suite() );
suite.addTest( CollectionTest.suite() );
suite.addTest( PersistentSetTest.suite() );
return suite;
}
}

View File

@ -0,0 +1,46 @@
package org.hibernate.test.collection.bag;
import java.util.List;
import java.util.ArrayList;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class BagOwner {
private String name;
private BagOwner parent;
private List children = new ArrayList();
public BagOwner() {
}
public BagOwner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BagOwner getParent() {
return parent;
}
public void setParent(BagOwner parent) {
this.parent = parent;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.collection.bag">
<class name="BagOwner">
<id name="name" column="NAME" type="string" />
<many-to-one name="parent" class="BagOwner" cascade="none" />
<bag name="children" inverse="true" cascade="all">
<key column="PARENT" />
<one-to-many class="BagOwner" />
</bag>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,70 @@
package org.hibernate.test.collection.bag;
import java.util.ArrayList;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.collection.PersistentBag;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* Tests related to operations on a PersistentBag.
*
* @author Steve Ebersole
*/
public class PersistentBagTest extends FunctionalTestCase {
public PersistentBagTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "collection/bag/Mappings.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( PersistentBagTest.class );
}
public void testWriteMethodDirtying() {
BagOwner parent = new BagOwner( "root" );
BagOwner child = new BagOwner( "c1" );
parent.getChildren().add( child );
child.setParent( parent );
BagOwner otherChild = new BagOwner( "c2" );
Session session = openSession();
session.beginTransaction();
session.save( parent );
session.flush();
// at this point, the list on parent has now been replaced with a PersistentBag...
PersistentBag children = ( PersistentBag ) parent.getChildren();
assertFalse( children.remove( otherChild ) );
assertFalse( children.isDirty() );
ArrayList otherCollection = new ArrayList();
otherCollection.add( child );
assertFalse( children.retainAll( otherCollection ) );
assertFalse( children.isDirty() );
otherCollection = new ArrayList();
otherCollection.add( otherChild );
assertFalse( children.removeAll( otherCollection ) );
assertFalse( children.isDirty() );
children.clear();
session.delete( child );
assertTrue( children.isDirty() );
session.flush();
children.clear();
assertFalse( children.isDirty() );
session.delete( parent );
session.getTransaction().commit();
session.close();
}
}

View File

@ -0,0 +1,37 @@
package org.hibernate.test.collection.idbag;
import java.util.List;
import java.util.ArrayList;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class IdbagOwner {
private String name;
private List children = new ArrayList();
public IdbagOwner() {
}
public IdbagOwner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.collection.idbag">
<class name="IdbagOwner">
<id name="name" column="NAME" type="string" />
<idbag name="children" cascade="all" table="idbag_owner_children">
<collection-id column="CHILD" type="long">
<generator class="increment"/>
</collection-id>
<key column="PARENT_FK" />
<many-to-many column="CHILD_FK" class="IdbagOwner" />
</idbag>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,69 @@
package org.hibernate.test.collection.idbag;
import java.util.ArrayList;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.collection.PersistentIdentifierBag;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* Tests related to operations on a PersistentIdentifierBag
*
* @author Steve Ebersole
*/
public class PersistentIdBagTest extends FunctionalTestCase {
public PersistentIdBagTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "collection/idbag/Mappings.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( PersistentIdBagTest.class );
}
public void testWriteMethodDirtying() {
IdbagOwner parent = new IdbagOwner( "root" );
IdbagOwner child = new IdbagOwner( "c1" );
parent.getChildren().add( child );
IdbagOwner otherChild = new IdbagOwner( "c2" );
Session session = openSession();
session.beginTransaction();
session.save( parent );
session.flush();
// at this point, the list on parent has now been replaced with a PersistentBag...
PersistentIdentifierBag children = ( PersistentIdentifierBag ) parent.getChildren();
assertFalse( children.remove( otherChild ) );
assertFalse( children.isDirty() );
ArrayList otherCollection = new ArrayList();
otherCollection.add( child );
assertFalse( children.retainAll( otherCollection ) );
assertFalse( children.isDirty() );
otherCollection = new ArrayList();
otherCollection.add( otherChild );
assertFalse( children.removeAll( otherCollection ) );
assertFalse( children.isDirty() );
children.clear();
session.delete( child );
assertTrue( children.isDirty() );
session.flush();
children.clear();
assertFalse( children.isDirty() );
session.delete( parent );
session.getTransaction().commit();
session.close();
}
}

View File

@ -0,0 +1,46 @@
package org.hibernate.test.collection.list;
import java.util.List;
import java.util.ArrayList;
/**
* {@inheritDoc}
*
* @author Steve Ebersole
*/
public class ListOwner {
private String name;
private ListOwner parent;
private List children = new ArrayList();
public ListOwner() {
}
public ListOwner(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ListOwner getParent() {
return parent;
}
public void setParent(ListOwner parent) {
this.parent = parent;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.collection.list">
<class name="ListOwner">
<id name="name" column="NAME" type="string" />
<many-to-one name="parent" class="ListOwner" cascade="none" />
<list name="children" inverse="true" cascade="all">
<key column="PARENT" />
<list-index column="LIST_INDEX"/>
<one-to-many class="ListOwner" />
</list>
</class>
</hibernate-mapping>

View File

@ -0,0 +1,70 @@
package org.hibernate.test.collection.list;
import java.util.ArrayList;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.collection.PersistentList;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
* Tests related to operations on a PersistentList
*
* @author Steve Ebersole
*/
public class PersistentListTest extends FunctionalTestCase {
public PersistentListTest(String name) {
super( name );
}
public String[] getMappings() {
return new String[] { "collection/list/Mappings.hbm.xml" };
}
public static Test suite() {
return new FunctionalTestClassTestSuite( PersistentListTest.class );
}
public void testWriteMethodDirtying() {
ListOwner parent = new ListOwner( "root" );
ListOwner child = new ListOwner( "c1" );
parent.getChildren().add( child );
child.setParent( parent );
ListOwner otherChild = new ListOwner( "c2" );
Session session = openSession();
session.beginTransaction();
session.save( parent );
session.flush();
// at this point, the list on parent has now been replaced with a PersistentList...
PersistentList children = ( PersistentList ) parent.getChildren();
assertFalse( children.remove( otherChild ) );
assertFalse( children.isDirty() );
ArrayList otherCollection = new ArrayList();
otherCollection.add( child );
assertFalse( children.retainAll( otherCollection ) );
assertFalse( children.isDirty() );
otherCollection = new ArrayList();
otherCollection.add( otherChild );
assertFalse( children.removeAll( otherCollection ) );
assertFalse( children.isDirty() );
children.clear();
session.delete( child );
assertTrue( children.isDirty() );
session.flush();
children.clear();
assertFalse( children.isDirty() );
session.delete( parent );
session.getTransaction().commit();
session.close();
}
}

View File

@ -0,0 +1,34 @@
package org.hibernate.test.collection.map;
/**
* todo: describe Child
*
* @author Steve Ebersole
*/
public class Child {
private String name;
private Parent parent;
public Child() {
}
public Child(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.collection.map">
<class name="Parent">
<id name="name" column="NAME" type="string" />
<map name="children" inverse="true" cascade="all">
<key column="PARENT" />
<map-key type="string" />
<one-to-many class="Child" />
</map>
</class>
<class name="Child">
<id name="name" column="NAME" type="string"/>
<many-to-one name="parent" class="Parent" cascade="none" />
</class>
</hibernate-mapping>

Some files were not shown because too many files have changed in this diff Show More