You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(22) |
Nov
(308) |
Dec
(131) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(369) |
Feb
(171) |
Mar
(236) |
Apr
(187) |
May
(218) |
Jun
(217) |
Jul
(127) |
Aug
(448) |
Sep
(270) |
Oct
(231) |
Nov
(422) |
Dec
(255) |
2004 |
Jan
(111) |
Feb
(73) |
Mar
(338) |
Apr
(351) |
May
(349) |
Jun
(495) |
Jul
(394) |
Aug
(1048) |
Sep
(499) |
Oct
(142) |
Nov
(269) |
Dec
(638) |
2005 |
Jan
(825) |
Feb
(1272) |
Mar
(593) |
Apr
(690) |
May
(950) |
Jun
(958) |
Jul
(767) |
Aug
(839) |
Sep
(525) |
Oct
(449) |
Nov
(585) |
Dec
(455) |
2006 |
Jan
(603) |
Feb
(656) |
Mar
(195) |
Apr
(114) |
May
(136) |
Jun
(100) |
Jul
(128) |
Aug
(68) |
Sep
(7) |
Oct
(1) |
Nov
(1) |
Dec
(8) |
2007 |
Jan
(4) |
Feb
(3) |
Mar
(8) |
Apr
(16) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(23) |
Sep
(15) |
Oct
(5) |
Nov
(7) |
Dec
(5) |
2008 |
Jan
(5) |
Feb
(1) |
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
Author: epbernard Date: 2006-06-10 23:50:42 -0400 (Sat, 10 Jun 2006) New Revision: 10010 Added: trunk/HibernateExt/metadata/lib/lucene-core-2.0.0.jar Removed: trunk/HibernateExt/metadata/lib/lucene-1.4.3.jar Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/lucene/LuceneTest.java Log: ANN-367 Lucene version update ANN-368 Index keywork is now decapitalized Deleted: trunk/HibernateExt/metadata/lib/lucene-1.4.3.jar =================================================================== (Binary files differ) Added: trunk/HibernateExt/metadata/lib/lucene-core-2.0.0.jar =================================================================== (Binary files differ) Property changes on: trunk/HibernateExt/metadata/lib/lucene-core-2.0.0.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java 2006-06-10 03:24:05 UTC (rev 10009) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java 2006-06-11 03:50:42 UTC (rev 10010) @@ -9,6 +9,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import java.beans.Introspector; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; @@ -18,6 +19,7 @@ import org.hibernate.HibernateException; import org.hibernate.cfg.annotations.Version; +//TODO handle attribute (only getters are handled currently) public class DocumentBuilder<T> { static { @@ -36,10 +38,10 @@ private String idKeywordName; private final Analyzer analyzer; - public DocumentBuilder(Class clazz, Analyzer analyzer, File indexDir) { + public DocumentBuilder(Class<?> clazz, Analyzer analyzer, File indexDir) { //this.beanClass = clazz; this.analyzer = analyzer; - String fileName = getTypeName( clazz, ( (Indexed) clazz.getAnnotation( Indexed.class ) ).index() ); + String fileName = getTypeName( clazz, ( clazz.getAnnotation( Indexed.class ) ).index() ); file = new File( indexDir, fileName ); for ( Class currClass = clazz; currClass != null ; currClass = currClass.getSuperclass() ) { @@ -96,26 +98,27 @@ public Document getDocument(T instance, Serializable id) { Document doc = new Document(); - doc.add( Field.Keyword( idKeywordName, id.toString() ) ); + doc.add( new Field( idKeywordName, id.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED ) ); for ( int i = 0; i < keywordNames.size() ; i++ ) { Member member = keywordGetters.get( i ); Object value = getValue( member, instance ); if ( value != null ) { - doc.add( Field.Keyword( keywordNames.get( i ), toString( value ) ) ); + doc.add( new Field( keywordNames.get( i ), toString( value ), Field.Store.YES, Field.Index.UN_TOKENIZED ) ); } } for ( int i = 0; i < textNames.size() ; i++ ) { Object value = getValue( textGetters.get( i ), instance ); if ( value != null ) { - doc.add( Field.Text( textNames.get( i ), toString( value ) ) ); + doc.add( new Field( textNames.get( i ), toString( value ), Field.Store.YES, Field.Index.TOKENIZED) ); } } for ( int i = 0; i < unstoredNames.size() ; i++ ) { Object value = getValue( unstoredGetters.get( i ), instance ); if ( value != null ) { - doc.add( Field.UnStored( unstoredNames.get( i ), toString( value ) ) ); + doc.add( new Field( unstoredNames.get( i ), toString( value ), Field.Store.NO, Field.Index.TOKENIZED ) ); } } + return doc; } @@ -128,8 +131,16 @@ } private static String getAttributeName(Method method, String name) { - //FIXME: yuk! what about "is" - return "".equals( name ) ? method.getName().substring( 3 ) : name; + if( ! "".equals( name ) ) return name; //explicit field name + + //decapitalize + String methodName = method.getName(); + //FIXME we probably should exclude methods not starting with "get" nor "is" + int startIndex = 3; + if( methodName.startsWith("is") ) { + startIndex = 2; + } + return Introspector.decapitalize( methodName.substring( startIndex ) ); } private static String getTypeName(Class clazz, String name) { Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java 2006-06-10 03:24:05 UTC (rev 10009) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java 2006-06-11 03:50:42 UTC (rev 10010) @@ -41,7 +41,7 @@ public class LuceneEventListener implements PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener, Initializable { - private Map<Class, DocumentBuilder> documentBuilders = new HashMap<Class, DocumentBuilder>(); + private Map<Class, DocumentBuilder<Object>> documentBuilders = new HashMap<Class, DocumentBuilder<Object>>(); private boolean initialized; private static final Log log = LogFactory.getLog( LuceneEventListener.class ); @@ -90,10 +90,10 @@ Iterator iter = cfg.getClassMappings(); while ( iter.hasNext() ) { PersistentClass clazz = (PersistentClass) iter.next(); - Class mappedClass = clazz.getMappedClass(); + Class<?> mappedClass = clazz.getMappedClass(); if ( mappedClass != null ) { if ( mappedClass.getAnnotation( Indexed.class ) != null ) { - final DocumentBuilder documentBuilder = new DocumentBuilder( mappedClass, analyzer, indexDir ); + final DocumentBuilder<Object> documentBuilder = new DocumentBuilder<Object>( mappedClass, analyzer, indexDir ); documentBuilders.put( mappedClass, documentBuilder ); // try { // IndexWriter iw = new IndexWriter( documentBuilder.getFile(), new StopAnalyzer(), true ); @@ -118,7 +118,7 @@ public void onPostInsert(PostInsertEvent event) { final Object entity = event.getEntity(); - DocumentBuilder builder = documentBuilders.get( entity.getClass() ); + DocumentBuilder<Object> builder = documentBuilders.get( entity.getClass() ); if ( builder != null ) { add( entity, builder, event.getId() ); } @@ -126,7 +126,7 @@ public void onPostUpdate(PostUpdateEvent event) { final Object entity = event.getEntity(); - DocumentBuilder builder = documentBuilders.get( entity.getClass() ); + DocumentBuilder<Object> builder = documentBuilders.get( entity.getClass() ); if ( builder != null ) { final Serializable id = event.getId(); remove( builder, id ); @@ -134,12 +134,12 @@ } } - private void remove(DocumentBuilder builder, Serializable id) { + private void remove(DocumentBuilder<?> builder, Serializable id) { Term term = builder.getTerm( id ); log.debug( "removing: " + term ); try { IndexReader reader = IndexReader.open( builder.getFile() ); - reader.delete( term ); + reader.deleteDocuments( term ); reader.close(); } catch (IOException ioe) { @@ -147,9 +147,11 @@ } } - private void add(final Object entity, final DocumentBuilder builder, final Serializable id) { + private void add(final Object entity, final DocumentBuilder<Object> builder, final Serializable id) { Document doc = builder.getDocument( entity, id ); - log.debug( "adding: " + doc ); + if( log.isDebugEnabled() ) { + log.debug( "adding: " + doc ); + } try { File file = builder.getFile(); IndexWriter writer = new IndexWriter( file, builder.getAnalyzer(), ! file.exists() ); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/lucene/LuceneTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/lucene/LuceneTest.java 2006-06-10 03:24:05 UTC (rev 10009) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/lucene/LuceneTest.java 2006-06-11 03:50:42 UTC (rev 10010) @@ -78,7 +78,7 @@ docs = reader.termDocs( new Term( "Title", "Action" ) ); doc = reader.document( docs.doc() ); assertFalse( docs.next() ); - assertEquals( "1", doc.getField( "Id" ).stringValue() ); + assertEquals( "1", doc.getField( "id" ).stringValue() ); reader.close(); s = getSessions().openSession(); @@ -109,7 +109,7 @@ docs = reader.termDocs( new Term( "Title", "Seam" ) ); doc = reader.document( docs.doc() ); assertFalse( docs.next() ); - assertEquals( "2", doc.getField( "Id" ).stringValue() ); + assertEquals( "2", doc.getField( "id" ).stringValue() ); reader.close(); s = getSessions().openSession(); |
From: <hib...@li...> - 2006-06-10 03:24:14
|
Author: epbernard Date: 2006-06-09 23:24:05 -0400 (Fri, 09 Jun 2006) New Revision: 10009 Added: trunk/Hibernate3/src/org/hibernate/type/AbstractBynaryType.java trunk/Hibernate3/src/org/hibernate/type/AbstractCharArrayType.java trunk/Hibernate3/src/org/hibernate/type/CharArrayType.java trunk/Hibernate3/src/org/hibernate/type/CharacterArrayType.java trunk/Hibernate3/src/org/hibernate/type/WrapperBinaryType.java Modified: trunk/Hibernate3/etc/log4j.properties trunk/Hibernate3/src/org/hibernate/Hibernate.java trunk/Hibernate3/src/org/hibernate/type/BinaryType.java trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java Log: HHH-1826 built in support for Byte[] Character[] char[] Modified: trunk/Hibernate3/etc/log4j.properties =================================================================== --- trunk/Hibernate3/etc/log4j.properties 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/etc/log4j.properties 2006-06-10 03:24:05 UTC (rev 10009) @@ -14,8 +14,8 @@ log4j.rootLogger=warn, stdout -log4j.logger.org.hibernate=info -#log4j.logger.org.hibernate=debug +#log4j.logger.org.hibernate=info +log4j.logger.org.hibernate=debug ### log HQL query parser activity #log4j.logger.org.hibernate.hql.ast.AST=debug Modified: trunk/Hibernate3/src/org/hibernate/Hibernate.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/Hibernate.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/Hibernate.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -53,6 +53,9 @@ import org.hibernate.type.TrueFalseType; import org.hibernate.type.Type; import org.hibernate.type.YesNoType; +import org.hibernate.type.CharArrayType; +import org.hibernate.type.WrapperBinaryType; +import org.hibernate.type.CharacterArrayType; import org.hibernate.usertype.CompositeUserType; /** @@ -140,6 +143,18 @@ */ public static final NullableType BINARY = new BinaryType(); /** + * Hibernate <tt>wrapper-binary</tt> type. + */ + public static final NullableType WRAPPER_BINARY = new WrapperBinaryType(); + /** + * Hibernate char[] type. + */ + public static final NullableType CHAR_ARRAY = new CharArrayType(); + /** + * Hibernate Character[] type. + */ + public static final NullableType CHARACTER_ARRAY = new CharacterArrayType(); + /** * Hibernate <tt>text</tt> type. */ public static final NullableType TEXT = new TextType(); Added: trunk/Hibernate3/src/org/hibernate/type/AbstractBynaryType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/AbstractBynaryType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/AbstractBynaryType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -0,0 +1,166 @@ +//$Id: $ +package org.hibernate.type; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.ResultSet; +import java.sql.Types; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Comparator; + +import org.hibernate.HibernateException; +import org.hibernate.EntityMode; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.cfg.Environment; + +/** + * Logic to bind stream of byte into a VARBINARY + * + * @author Gavin King + * @author Emmanuel Bernard + */ +public abstract class AbstractBynaryType extends MutableType implements VersionType, Comparator { + + /** + * Convert the byte[] into the expected object type + */ + abstract protected Object toExternalFormat(byte[] bytes); + + /** + * Convert the object into the internal byte[] representation + */ + abstract protected byte[] toInternalFormat(Object bytes); + + public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { + byte[] internalValue = toInternalFormat( value ); + if ( Environment.useStreamsForBinary() ) { + st.setBinaryStream( index, new ByteArrayInputStream( internalValue ), internalValue.length ); + } + else { + st.setBytes( index, internalValue ); + } + } + + public Object get(ResultSet rs, String name) throws HibernateException, SQLException { + + if ( Environment.useStreamsForBinary() ) { + + InputStream inputStream = rs.getBinaryStream(name); + + if (inputStream==null) return toExternalFormat( null ); // is this really necessary? + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048); + byte[] buffer = new byte[2048]; + + try { + while (true) { + int amountRead = inputStream.read(buffer); + if (amountRead == -1) { + break; + } + outputStream.write(buffer, 0, amountRead); + } + + inputStream.close(); + outputStream.close(); + } + catch (IOException ioe) { + throw new HibernateException( "IOException occurred reading a binary value", ioe ); + } + + return toExternalFormat( outputStream.toByteArray() ); + + } + else { + return toExternalFormat( rs.getBytes(name) ); + } + } + + public int sqlType() { + return Types.VARBINARY; + } + + // VersionType impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Note : simply returns null for seed() and next() as the only known + // application of binary types for versioning is for use with the + // TIMESTAMP datatype supported by Sybase and SQL Server, which + // are completely db-generated values... + public Object seed(SessionImplementor session) { + return null; + } + + public Object next(Object current, SessionImplementor session) { + return current; + } + + public Comparator getComparator() { + return this; + } + + public int compare(Object o1, Object o2) { + return compare( o1, o2, null ); + } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public boolean isEqual(Object x, Object y) { + return x==y || ( x!=null && y!=null && java.util.Arrays.equals( toInternalFormat(x), toInternalFormat(y) ) ); + } + + public int getHashCode(Object x, EntityMode entityMode) { + byte[] bytes = toInternalFormat(x); + int hashCode = 1; + for ( int j=0; j<bytes.length; j++ ) { + hashCode = 31 * hashCode + bytes[j]; + } + return hashCode; + } + + public int compare(Object x, Object y, EntityMode entityMode) { + byte[] xbytes = toInternalFormat(x); + byte[] ybytes = toInternalFormat(y); + if ( xbytes.length < ybytes.length ) return -1; + if ( xbytes.length > ybytes.length ) return 1; + for ( int i=0; i<xbytes.length; i++ ) { + if ( xbytes[i] < ybytes[i] ) return -1; + if ( xbytes[i] > ybytes[i] ) return 1; + } + return 0; + } + + public abstract String getName(); + + public String toString(Object val) { + byte[] bytes = toInternalFormat(val); + StringBuffer buf = new StringBuffer(); + for ( int i=0; i<bytes.length; i++ ) { + String hexStr = Integer.toHexString( bytes[i] - Byte.MIN_VALUE ); + if ( hexStr.length()==1 ) buf.append('0'); + buf.append(hexStr); + } + return buf.toString(); + } + + public Object deepCopyNotNull(Object value) { + byte[] bytes = toInternalFormat(value); + byte[] result = new byte[bytes.length]; + System.arraycopy(bytes, 0, result, 0, bytes.length); + return toExternalFormat(result); + } + + public Object fromStringValue(String xml) throws HibernateException { + if (xml == null) + return null; + if (xml.length() % 2 != 0) + throw new IllegalArgumentException("The string is not a valid xml representation of a binary content."); + byte[] bytes = new byte[xml.length() / 2]; + for (int i = 0; i < bytes.length; i++) { + String hexStr = xml.substring(i * 2, (i + 1) * 2); + bytes[i] = (byte) (Integer.parseInt(hexStr, 16) + Byte.MIN_VALUE); + } + return toExternalFormat(bytes); + } + +} Added: trunk/Hibernate3/src/org/hibernate/type/AbstractCharArrayType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/AbstractCharArrayType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/AbstractCharArrayType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -0,0 +1,96 @@ +//$Id: $ +package org.hibernate.type; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.PreparedStatement; +import java.sql.Types; +import java.io.Reader; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.CharArrayReader; + +import org.hibernate.HibernateException; +import org.hibernate.dialect.Dialect; + +/** + * Logic to bind stream of char into a VARCHAR + * + * @author Emmanuel Bernard + */ +public abstract class AbstractCharArrayType extends MutableType { + + /** + * Convert the char[] into the expected object type + */ + abstract protected Object toExternalFormat(char[] chars); + + /** + * Convert the object into the internal char[] representation + */ + abstract protected char[] toInternalFormat(Object chars); + + public Object get(ResultSet rs, String name) throws SQLException { + Reader stream = rs.getCharacterStream(name); + if ( stream == null ) return toExternalFormat( null ); + CharArrayWriter writer = new CharArrayWriter(); + for(;;) { + try { + int c = stream.read(); + if ( c == -1) return toExternalFormat( writer.toCharArray() ); + writer.write( c ); + } + catch (IOException e) { + throw new HibernateException("Unable to read character stream from rs"); + } + } + } + + public abstract Class getReturnedClass(); + + public void set(PreparedStatement st, Object value, int index) throws SQLException { + char[] chars = toInternalFormat( value ); + st.setCharacterStream(index, new CharArrayReader(chars), chars.length); + } + + public int sqlType() { + return Types.VARCHAR; + } + + public String objectToSQLString(Object value, Dialect dialect) throws Exception { + + return '\'' + new String( toInternalFormat( value ) ) + '\''; + } + + public Object stringToObject(String xml) throws Exception { + if (xml == null) return toExternalFormat( null ); + int length = xml.length(); + char[] chars = new char[length]; + for (int index = 0 ; index < length ; index++ ) { + chars[index] = xml.charAt( index ); + } + return toExternalFormat( chars ); + } + + public String toString(Object value) { + if (value == null) return null; + return new String( toInternalFormat( value ) ); + } + + public Object fromStringValue(String xml) { + if (xml == null) return null; + int length = xml.length(); + char[] chars = new char[length]; + for (int index = 0 ; index < length ; index++ ) { + chars[index] = xml.charAt( index ); + } + return toExternalFormat( chars ); + } + + protected Object deepCopyNotNull(Object value) throws HibernateException { + char[] chars = toInternalFormat(value); + char[] result = new char[chars.length]; + System.arraycopy(chars, 0, result, 0, chars.length); + return toExternalFormat(result); + } +} Modified: trunk/Hibernate3/src/org/hibernate/type/BinaryType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/BinaryType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/BinaryType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -1,157 +1,24 @@ //$Id$ package org.hibernate.type; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Comparator; - -import org.hibernate.EntityMode; -import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.cfg.Environment; - /** * <tt>binary</tt>: A type that maps an SQL VARBINARY to a Java byte[]. * @author Gavin King */ -public class BinaryType extends MutableType implements VersionType, Comparator { +public class BinaryType extends AbstractBynaryType { - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - - if ( Environment.useStreamsForBinary() ) { - st.setBinaryStream( index, new ByteArrayInputStream( (byte[]) value ), ( (byte[]) value ).length ); - } - else { - st.setBytes( index, (byte[]) value ); - } + protected Object toExternalFormat(byte[] bytes) { + return bytes; } - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - - if ( Environment.useStreamsForBinary() ) { - - InputStream inputStream = rs.getBinaryStream(name); - - if (inputStream==null) return null; // is this really necessary? - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048); - byte[] buffer = new byte[2048]; - - try { - while (true) { - int amountRead = inputStream.read(buffer); - if (amountRead == -1) { - break; - } - outputStream.write(buffer, 0, amountRead); - } - - inputStream.close(); - outputStream.close(); - } - catch (IOException ioe) { - throw new HibernateException( "IOException occurred reading a binary value", ioe ); - } - - return outputStream.toByteArray(); - - } - else { - return rs.getBytes(name); - } + protected byte[] toInternalFormat(Object bytes) { + return (byte[]) bytes; } - public int sqlType() { - return Types.VARBINARY; - } - public Class getReturnedClass() { return byte[].class; } - // VersionType impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // Note : simply returns null for seed() and next() as the only known - // application of binary types for versioning is for use with the - // TIMESTAMP datatype supported by Sybase and SQL Server, which - // are completely db-generated values... - public Object seed(SessionImplementor session) { - return null; - } - - public Object next(Object current, SessionImplementor session) { - return current; - } - - public Comparator getComparator() { - return this; - } - - public int compare(Object o1, Object o2) { - return compare( o1, o2, null ); - } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - public boolean isEqual(Object x, Object y) { - return x==y || ( x!=null && y!=null && java.util.Arrays.equals( (byte[]) x, (byte[]) y ) ); - } - - public int getHashCode(Object x, EntityMode entityMode) { - byte[] bytes = (byte[]) x; - int hashCode = 1; - for ( int j=0; j<bytes.length; j++ ) { - hashCode = 31 * hashCode + bytes[j]; - } - return hashCode; - } - - public int compare(Object x, Object y, EntityMode entityMode) { - byte[] xbytes = (byte[]) x; - byte[] ybytes = (byte[]) y; - if ( xbytes.length < ybytes.length ) return -1; - if ( xbytes.length > ybytes.length ) return 1; - for ( int i=0; i<xbytes.length; i++ ) { - if ( xbytes[i] < ybytes[i] ) return -1; - if ( xbytes[i] > ybytes[i] ) return 1; - } - return 0; - } - public String getName() { return "binary"; } - public String toString(Object val) { - byte[] bytes = ( byte[] ) val; - StringBuffer buf = new StringBuffer(); - for ( int i=0; i<bytes.length; i++ ) { - String hexStr = Integer.toHexString( bytes[i] - Byte.MIN_VALUE ); - if ( hexStr.length()==1 ) buf.append('0'); - buf.append(hexStr); - } - return buf.toString(); - } - - public Object deepCopyNotNull(Object value) { - byte[] bytes = (byte[]) value; - byte[] result = new byte[bytes.length]; - System.arraycopy(bytes, 0, result, 0, bytes.length); - return result; - } - - public Object fromStringValue(String xml) throws HibernateException { - if (xml == null) - return null; - if (xml.length() % 2 != 0) - throw new IllegalArgumentException("The string is not a valid xml representation of a binary content."); - byte[] bytes = new byte[xml.length() / 2]; - for (int i = 0; i < bytes.length; i++) { - String hexStr = xml.substring(i * 2, (i + 1) * 2); - bytes[i] = (byte) (Integer.parseInt(hexStr, 16) + Byte.MIN_VALUE); - } - return bytes; - } } Added: trunk/Hibernate3/src/org/hibernate/type/CharArrayType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/CharArrayType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/CharArrayType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -0,0 +1,23 @@ +//$Id: $ +package org.hibernate.type; + +/** + * put char[] into VARCHAR + * @author Emmanuel Bernard + */ +public class CharArrayType extends AbstractCharArrayType { + + protected Object toExternalFormat(char[] chars) { + return chars; + } + + protected char[] toInternalFormat(Object chars) { + return (char[]) chars; + } + + public Class getReturnedClass() { + return char[].class; + } + + public String getName() { return "characters"; } +} Added: trunk/Hibernate3/src/org/hibernate/type/CharacterArrayType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/CharacterArrayType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/CharacterArrayType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -0,0 +1,37 @@ +//$Id: $ +package org.hibernate.type; + +import org.hibernate.HibernateException; + +/** + * Bridge Character[] and VARCHAR + * @author Emmanuel Bernard + */ +public class CharacterArrayType extends AbstractCharArrayType { + protected Object toExternalFormat(char[] chars) { + if (chars == null) return null; + Character[] characters = new Character[chars.length]; + for (int i = 0 ; i < chars.length ; i++) { + characters[i] = new Character( chars[i] ); + } + return characters; + } + + protected char[] toInternalFormat(Object value) { + if (value == null) return null; + Character[] characters = (Character[]) value; + char[] chars = new char[characters.length]; + for (int i = 0 ; i < characters.length ; i++) { + if (characters[i] == null) + throw new HibernateException("Unable to store an Character[] when one of its element is null"); + chars[i] = characters[i].charValue(); + } + return chars; + } + + public Class getReturnedClass() { + return Character[].class; + } + + public String getName() { return "wrapper-characters"; } +} Modified: trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/TypeFactory.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -101,6 +101,12 @@ basics.put( Class.class.getName(), Hibernate.CLASS ); basics.put( byte[].class.getName(), Hibernate.BINARY ); basics.put( "byte[]", Hibernate.BINARY ); + basics.put( Byte[].class.getName(), Hibernate.WRAPPER_BINARY ); + basics.put( "Byte[]", Hibernate.WRAPPER_BINARY ); + basics.put( char[].class.getName(), Hibernate.CHAR_ARRAY ); + basics.put( "char[]", Hibernate.CHAR_ARRAY ); + basics.put( Character[].class.getName(), Hibernate.CHARACTER_ARRAY ); + basics.put( "Character[]", Hibernate.CHARACTER_ARRAY ); basics.put( Blob.class.getName(), Hibernate.BLOB ); basics.put( Clob.class.getName(), Hibernate.CLOB ); basics.put( Serializable.class.getName(), Hibernate.SERIALIZABLE ); Added: trunk/Hibernate3/src/org/hibernate/type/WrapperBinaryType.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/type/WrapperBinaryType.java 2006-06-09 17:46:51 UTC (rev 10008) +++ trunk/Hibernate3/src/org/hibernate/type/WrapperBinaryType.java 2006-06-10 03:24:05 UTC (rev 10009) @@ -0,0 +1,41 @@ +//$Id: $ +package org.hibernate.type; + +import org.hibernate.HibernateException; + +/** + * @author Emmanuel Bernard + */ +public class WrapperBinaryType extends AbstractBynaryType { + protected Object toExternalFormat(byte[] bytes) { + if (bytes == null) return null; + int length = bytes.length; + Byte[] result = new Byte[length]; + for ( int index = 0; index < length ; index++ ) { + result[index] = new Byte( bytes[index] ); + } + return result; + } + + protected byte[] toInternalFormat(Object val) { + if (val == null) return null; + Byte[] bytes = (Byte[]) val; + int length = bytes.length; + byte[] result = new byte[length]; + for ( int i = 0; i < length ; i++ ) { + if (bytes[i] == null) + throw new HibernateException("Unable to store an Byte[] when one of its element is null"); + result[i] = bytes[i].byteValue(); + } + return result; + } + + public Class getReturnedClass() { + return Byte[].class; + } + + public String getName() { + //TODO find a decent name before documenting + return "wrapper-binary"; + } +} |
From: <hib...@li...> - 2006-06-09 17:47:56
|
Author: ste...@jb... Date: 2006-06-09 13:46:51 -0400 (Fri, 09 Jun 2006) New Revision: 10008 Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java Modified: trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml Log: persist() with non-cascaded associations to transient objects with assigned identifier strategies Modified: trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-06-09 17:46:51 UTC (rev 10008) @@ -210,16 +210,18 @@ return null; } else { - Serializable id = session.getContextEntityIdentifier(object); - if ( id==null ) { - if ( isTransient(entityName, object, Boolean.FALSE, session) ) { + Serializable id = session.getContextEntityIdentifier( object ); + if ( id == null ) { + // context-entity-identifier returns null explicitly if the entity + // is not associated with the persistence context; so make some + // deeper checks... + if ( isTransient(entityName, object, null, session) ) { throw new TransientObjectException( "object references an unsaved transient instance - save the transient instance before flushing: " + entityName == null ? session.guessEntityName( object ) : entityName ); } - id = session.getEntityPersister(entityName, object) - .getIdentifier( object, session.getEntityMode() ); + id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() ); } return id; } Modified: trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-06-09 17:46:51 UTC (rev 10008) @@ -19,6 +19,7 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.QueryException; +import org.hibernate.TransientObjectException; import org.hibernate.cache.CacheConcurrencyStrategy; import org.hibernate.cache.CacheException; import org.hibernate.cache.entry.CacheEntryStructure; @@ -33,6 +34,7 @@ import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionImplementor; import org.hibernate.engine.SubselectFetch; +import org.hibernate.engine.ForeignKeys; import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.exception.SQLExceptionConverter; import org.hibernate.id.IdentifierGenerator; @@ -1582,6 +1584,9 @@ rs.close(); } } + catch( TransientObjectException e ) { + return false; + } finally { session.getBatcher().closeStatement( st ); } Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 17:46:51 UTC (rev 10008) @@ -2,8 +2,11 @@ import org.hibernate.test.jpa.AbstractJPATest; import org.hibernate.Session; +import org.hibernate.TransientObjectException; import org.hibernate.event.def.DefaultPersistOnFlushEventListener; import org.hibernate.cfg.Configuration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * todo: describe CascadeTest @@ -11,6 +14,9 @@ * @author Steve Ebersole */ public class CascadeTest extends AbstractJPATest { + + public static final Log log = LogFactory.getLog( CascadeTest.class ); + public CascadeTest(String name) { super( name ); } @@ -37,7 +43,14 @@ Child c = new Child( "c1" ); c.setParent( p ); s.persist( c ); - s.getTransaction().commit(); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + } s.close(); s = openSession(); @@ -47,4 +60,26 @@ s.getTransaction().commit(); s.close(); } + + public void testPersistOnFlushWithNoCascadeToTransientAssociationWithAssignedIdentifier() { + // according to the JPA spec, persist()ing an entity should throw + // an exception when said entity contains a reference to a transient + // asoociation where that association is not marked for cascading + // the persist operation... + Session s = openSession(); + s.beginTransaction(); + ParentAssigned p = new ParentAssigned( new Long( 1 ), "p1" ); + ChildAssigned c = new ChildAssigned( new Long( 2 ), "c1" ); + c.setParent( p ); + s.persist( c ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete ChildAssigned" ).executeUpdate(); + s.createQuery( "delete ParentAssigned" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } } Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-09 17:46:51 UTC (rev 10008) @@ -0,0 +1,40 @@ +package org.hibernate.test.jpa.cascade; + +/** + * Child, but with an assigned identifier. + * + * @author Steve Ebersole + */ +public class ChildAssigned { + private Long id; + private String name; + private ParentAssigned parent; + + public ChildAssigned() { + } + + public ChildAssigned(Long id, String name) { + this.id = id; + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ParentAssigned getParent() { + return parent; + } + + public void setParent(ParentAssigned parent) { + this.parent = parent; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-09 17:46:51 UTC (rev 10008) @@ -0,0 +1,31 @@ +package org.hibernate.test.jpa.cascade; + +/** + * Parent, but with an assigned identifier. + * + * @author Steve Ebersole + */ +public class ParentAssigned { + private Long id; + private String name; + + public ParentAssigned() { + } + + public ParentAssigned(Long id, String name) { + this.id = id; + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-09 17:44:51 UTC (rev 10007) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-09 17:46:51 UTC (rev 10008) @@ -2,7 +2,7 @@ "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="org.hibernate.test.jpa.cascade"> +<hibernate-mapping package="org.hibernate.test.jpa.cascade" default-access="field"> <class name="Parent" table="PARENT"> <id name="id" column="ID" type="long"> @@ -19,4 +19,19 @@ <many-to-one name="parent" class="Parent" cascade="none"/> </class> + <class name="ParentAssigned" table="PARENT"> + <id name="id" column="ID" type="long"> + <generator class="assigned"/> + </id> + <property name="name"/> + </class> + + <class name="ChildAssigned" table="CHILD"> + <id name="id" column="ID" type="long"> + <generator class="assigned"/> + </id> + <property name="name"/> + <many-to-one name="parent" class="ParentAssigned" cascade="none"/> + </class> + </hibernate-mapping> \ No newline at end of file |
From: <hib...@li...> - 2006-06-09 17:45:09
|
Author: ste...@jb... Date: 2006-06-09 13:44:51 -0400 (Fri, 09 Jun 2006) New Revision: 10007 Modified: trunk/Hibernate3/src/org/hibernate/engine/NamedSQLQueryDefinition.java Log: cleanup Modified: trunk/Hibernate3/src/org/hibernate/engine/NamedSQLQueryDefinition.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/NamedSQLQueryDefinition.java 2006-06-09 15:03:23 UTC (rev 10006) +++ trunk/Hibernate3/src/org/hibernate/engine/NamedSQLQueryDefinition.java 2006-06-09 17:44:51 UTC (rev 10007) @@ -24,54 +24,91 @@ private final boolean callable; private String resultSetRef; - /** backward compatibility: to be removed after HA 3.2beta5*/ + /** + * This form used to construct a NamedSQLQueryDefinition from the binder + * code when a the result-set mapping information is explicitly + * provided in the query definition (i.e., no resultset-mapping used) + * + * @param query The sql query string + * @param queryReturns The in-lined query return definitions + * @param scalarReturns The in-lined scalar query return definitions + * @param querySpaces Any specified query spaces (used for auto-flushing) + * @param cacheable Whether the query results are cacheable + * @param cacheRegion If cacheable, the region into which to store the results + * @param timeout A JDBC-level timeout to be applied + * @param fetchSize A JDBC-level fetch-size to be applied + * @param flushMode The flush mode to use for this query + * @param cacheMode The cache mode to use during execution and subsequent result loading + * @param readOnly Whether returned entities should be marked as read-only in the session + * @param comment Any sql comment to be applied to the query + * @param parameterTypes parameter type map + * @param callable Does the query string represent a callable object (i.e., proc) + */ public NamedSQLQueryDefinition( - String query, - SQLQueryReturn[] queryReturns, - SQLQueryScalarReturn[] scalarReturns, - List querySpaces, - boolean cacheable, - String cacheRegion, - Integer timeout, - Integer fetchSize, - FlushMode flushMode, - Map parameterTypes, - boolean callable - ) { - this( - query, - queryReturns, - scalarReturns, - querySpaces, + String query, + SQLQueryReturn[] queryReturns, + SQLQueryScalarReturn[] scalarReturns, + List querySpaces, + boolean cacheable, + String cacheRegion, + Integer timeout, + Integer fetchSize, + FlushMode flushMode, + CacheMode cacheMode, + boolean readOnly, + String comment, + Map parameterTypes, + boolean callable) { + super( + query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */ cacheable, cacheRegion, timeout, fetchSize, flushMode, - null, - false, - null, - parameterTypes, - callable + cacheMode, + readOnly, + comment, + parameterTypes ); + this.queryReturns = queryReturns; + this.scalarReturns = scalarReturns; + this.querySpaces = querySpaces; + this.callable = callable; } + /** + * This form used to construct a NamedSQLQueryDefinition from the binder + * code when a resultset-mapping reference is used. + * + * @param query The sql query string + * @param resultSetRef The resultset-mapping name + * @param querySpaces Any specified query spaces (used for auto-flushing) + * @param cacheable Whether the query results are cacheable + * @param cacheRegion If cacheable, the region into which to store the results + * @param timeout A JDBC-level timeout to be applied + * @param fetchSize A JDBC-level fetch-size to be applied + * @param flushMode The flush mode to use for this query + * @param cacheMode The cache mode to use during execution and subsequent result loading + * @param readOnly Whether returned entities should be marked as read-only in the session + * @param comment Any sql comment to be applied to the query + * @param parameterTypes parameter type map + * @param callable Does the query string represent a callable object (i.e., proc) + */ public NamedSQLQueryDefinition( - String query, - SQLQueryReturn[] queryReturns, - SQLQueryScalarReturn[] scalarReturns, - List querySpaces, - boolean cacheable, - String cacheRegion, - Integer timeout, - Integer fetchSize, - FlushMode flushMode, - CacheMode cacheMode, - boolean readOnly, - String comment, - Map parameterTypes, - boolean callable - ) { + String query, + String resultSetRef, + List querySpaces, + boolean cacheable, + String cacheRegion, + Integer timeout, + Integer fetchSize, + FlushMode flushMode, + CacheMode cacheMode, + boolean readOnly, + String comment, + Map parameterTypes, + boolean callable) { super( query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */ cacheable, @@ -84,24 +121,37 @@ comment, parameterTypes ); - this.queryReturns = queryReturns; - this.scalarReturns = scalarReturns; + this.resultSetRef = resultSetRef; this.querySpaces = querySpaces; this.callable = callable; } + /** + * This form used from annotations (?). Essentially the same as the above using a + * resultset-mapping reference, but without cacheMode, readOnly, and comment. + * + * @param query The sql query string + * @param resultSetRef The result-set-mapping name + * @param querySpaces Any specified query spaces (used for auto-flushing) + * @param cacheable Whether the query results are cacheable + * @param cacheRegion If cacheable, the region into which to store the results + * @param timeout A JDBC-level timeout to be applied + * @param fetchSize A JDBC-level fetch-size to be applied + * @param flushMode The flush mode to use for this query + * @param parameterTypes parameter type map + * @param callable Does the query string represent a callable object (i.e., proc) + */ public NamedSQLQueryDefinition( - String query, - String resultSetRef, - List querySpaces, - boolean cacheable, - String cacheRegion, - Integer timeout, - Integer fetchSize, - FlushMode flushMode, - Map parameterTypes, - boolean callable - ) { + String query, + String resultSetRef, + List querySpaces, + boolean cacheable, + String cacheRegion, + Integer timeout, + Integer fetchSize, + FlushMode flushMode, + Map parameterTypes, + boolean callable) { this( query, resultSetRef, @@ -119,38 +169,6 @@ ); } - public NamedSQLQueryDefinition( - String query, - String resultSetRef, - List querySpaces, - boolean cacheable, - String cacheRegion, - Integer timeout, - Integer fetchSize, - FlushMode flushMode, - CacheMode cacheMode, - boolean readOnly, - String comment, - Map parameterTypes, - boolean callable - ) { - super( - query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */ - cacheable, - cacheRegion, - timeout, - fetchSize, - flushMode, - cacheMode, - readOnly, - comment, - parameterTypes - ); - this.resultSetRef = resultSetRef; - this.querySpaces = querySpaces; - this.callable = callable; - } - public SQLQueryReturn[] getQueryReturns() { return queryReturns; } |
From: <hib...@li...> - 2006-06-09 15:03:41
|
Author: ste...@jb... Date: 2006-06-09 11:03:23 -0400 (Fri, 09 Jun 2006) New Revision: 10006 Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java Log: another test Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java 2006-06-09 14:35:09 UTC (rev 10005) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java 2006-06-09 15:03:23 UTC (rev 10006) @@ -19,6 +19,14 @@ public static Test suite() { return new TestSuite( JPAQLComplianceTest.class ); } + public void testAliasNameSameAsUnqualifiedEntityName() { + Session s = openSession(); + s.beginTransaction(); + s.createQuery( "select item from Item item" ).list(); + s.createQuery( "select item from Item item where item.name = 'a'" ).list(); + s.getTransaction().commit(); + s.close(); + } public void testNoSelectClause() { Session s = openSession(); |
From: <hib...@li...> - 2006-06-09 14:35:12
|
Author: ste...@jb... Date: 2006-06-09 10:35:09 -0400 (Fri, 09 Jun 2006) New Revision: 10005 Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml Log: test for persist() with reference to non-cascaded transient association Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 11:01:53 UTC (rev 10004) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 14:35:09 UTC (rev 10005) @@ -0,0 +1,50 @@ +package org.hibernate.test.jpa.cascade; + +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.Session; +import org.hibernate.event.def.DefaultPersistOnFlushEventListener; +import org.hibernate.cfg.Configuration; + +/** + * todo: describe CascadeTest + * + * @author Steve Ebersole + */ +public class CascadeTest extends AbstractJPATest { + public CascadeTest(String name) { + super( name ); + } + + protected String[] getMappings() { + return new String[] { "jpa/cascade/ParentChild.hbm.xml" }; + } + + protected void configure(Configuration cfg) { + super.configure( cfg ); +// cfg.setListeners( "create", new DefaultPersistOnFlushEventListener[] { new DefaultPersistOnFlushEventListener() } ); +// cfg.setListeners( "create-onflush", new DefaultPersistOnFlushEventListener[] { new DefaultPersistOnFlushEventListener() } ); + + } + + public void testPersistOnFlushWithNoCascadeToTransientAssociation() { + // according to the JPA spec, persist()ing an entity should throw + // an exception when said entity contains a reference to a transient + // asoociation where that association is not marked for cascading + // the persist operation... + Session s = openSession(); + s.beginTransaction(); + Parent p = new Parent( "p1" ); + Child c = new Child( "c1" ); + c.setParent( p ); + s.persist( c ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete Child" ).executeUpdate(); + s.createQuery( "delete Parent" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java 2006-06-09 11:01:53 UTC (rev 10004) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java 2006-06-09 14:35:09 UTC (rev 10005) @@ -0,0 +1,43 @@ +package org.hibernate.test.jpa.cascade; + +/** + * todo: describe Child + * + * @author Steve Ebersole + */ +public class Child { + private Long id; + private String name; + private Parent parent; + + public Child() { + } + + public Child(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 Parent getParent() { + return parent; + } + + public void setParent(Parent parent) { + this.parent = parent; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java 2006-06-09 11:01:53 UTC (rev 10004) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java 2006-06-09 14:35:09 UTC (rev 10005) @@ -0,0 +1,34 @@ +package org.hibernate.test.jpa.cascade; + +/** + * todo: describe Parent + * + * @author Steve Ebersole + */ +public class Parent { + private Long id; + private String name; + + public Parent() { + } + + public Parent(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; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-09 11:01:53 UTC (rev 10004) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-09 14:35:09 UTC (rev 10005) @@ -0,0 +1,22 @@ +<!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.jpa.cascade"> + + <class name="Parent" table="PARENT"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <property name="name"/> + </class> + + <class name="Child" table="CHILD"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <property name="name"/> + <many-to-one name="parent" class="Parent" cascade="none"/> + </class> + +</hibernate-mapping> \ No newline at end of file |
From: <hib...@li...> - 2006-06-09 11:01:59
|
Author: max...@jb... Date: 2006-06-09 07:01:53 -0400 (Fri, 09 Jun 2006) New Revision: 10004 Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/ConfigurationCompletion.java trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/HQLCompletionProposal.java trunk/HibernateExt/tools/src/test/org/hibernate/tool/ide/completion/ModelCompletionTest.java Log: put Property into the completion Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/ConfigurationCompletion.java =================================================================== --- trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/ConfigurationCompletion.java 2006-06-09 01:31:32 UTC (rev 10003) +++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/ConfigurationCompletion.java 2006-06-09 11:01:53 UTC (rev 10004) @@ -188,6 +188,7 @@ if (prefix.length() == 0 || candidate.startsWith(prefix)) { HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, HQLCompletionProposal.PROPERTY, candidate ); proposal.setEntityName( cmd.getEntityName() ); + proposal.setProperty( property ); proposal.setPropertyName( candidate ); hcc.accept( proposal); } @@ -323,6 +324,7 @@ HQLCompletionProposal proposal = createStartWithCompletionProposal( prefix, cursorPosition, HQLCompletionProposal.PROPERTY, candidate ); //proposal.setEntityName( cmd.getEntityName() ); ...we don't know here..TODO: pass in the "path" proposal.setPropertyName( candidate ); + proposal.setProperty(element); hcc.accept( proposal); } i++; Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/HQLCompletionProposal.java =================================================================== --- trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/HQLCompletionProposal.java 2006-06-09 01:31:32 UTC (rev 10003) +++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/ide/completion/HQLCompletionProposal.java 2006-06-09 11:01:53 UTC (rev 10004) @@ -1,7 +1,9 @@ package org.hibernate.tool.ide.completion; +import org.hibernate.mapping.Property; + public class HQLCompletionProposal { static final char[] NO_CHAR = new char[0]; @@ -55,6 +57,11 @@ * The propertyName, can be null. */ private String propertyName = null; + + /** + * The underlying property. Can be null. + */ + private Property property; public String getCompletion() { return completion; @@ -173,8 +180,14 @@ this.propertyName = propertyName; } + public void setProperty(Property element) { + this.property = element; + } + + public Property getProperty() { + return property; + } - } Modified: trunk/HibernateExt/tools/src/test/org/hibernate/tool/ide/completion/ModelCompletionTest.java =================================================================== --- trunk/HibernateExt/tools/src/test/org/hibernate/tool/ide/completion/ModelCompletionTest.java 2006-06-09 01:31:32 UTC (rev 10003) +++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/ide/completion/ModelCompletionTest.java 2006-06-09 11:01:53 UTC (rev 10004) @@ -379,6 +379,8 @@ //TODO: keep a path/context assertEquals("Product", proposal.getShortEntityName()); assertEquals("org.hibernate.tool.ide.completion.Product", proposal.getEntityName()); assertEquals("version", proposal.getPropertyName()); + assertNotNull(proposal.getProperty()); + assertEquals(proposal.getPropertyName(), proposal.getProperty().getName()); } |
Author: epbernard Date: 2006-06-08 21:31:32 -0400 (Thu, 08 Jun 2006) New Revision: 10003 Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/callbacks/CallbackAndDirtyTest.java trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java Log: EJB-194 EJB-195 Wrap QueryException EJB-196 (partial wrap TransientObjectException) Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java =================================================================== --- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -41,6 +41,8 @@ import org.hibernate.Transaction; import org.hibernate.UnresolvableObjectException; import org.hibernate.TypeMismatchException; +import org.hibernate.QueryException; +import org.hibernate.TransientObjectException; import org.hibernate.ejb.transaction.JoinableCMTTransaction; import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionImplementor; @@ -387,6 +389,7 @@ } protected void markAsRollback() { + log.debug( "mark transaction for rollback"); if ( tx.isActive() ) { tx.setRollbackOnly(); } @@ -574,6 +577,13 @@ else if ( e instanceof UnresolvableObjectException ) { throwPersistenceException( new EntityNotFoundException( e.getMessage() ) ); } + else if ( e instanceof QueryException ) { + throw new IllegalArgumentException( e ); + } + else if ( e instanceof TransientObjectException ) { + markAsRollback(); + throw new IllegalStateException( e ); //Spec 3.2.3 Synchronozation rules + } else { throwPersistenceException( new PersistenceException( e ) ); } Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java =================================================================== --- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Ejb3Configuration.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -837,6 +837,7 @@ //defaults different to Hibernate preparedProperties.setProperty( Environment.RELEASE_CONNECTIONS, "auto" ); + preparedProperties.setProperty( Environment.JPAQL_STRICT_COMPLIANCE, "true" ); //settings that always apply to a compliant EJB3 preparedProperties.setProperty( Environment.AUTOCOMMIT, "true" ); preparedProperties.setProperty( Environment.USE_IDENTIFIER_ROLLBACK, "false" ); Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java =================================================================== --- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/event/EJB3DeleteEventListener.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -1,7 +1,10 @@ //$Id$ package org.hibernate.ejb.event; +import java.io.Serializable; + import org.hibernate.event.EventSource; +import org.hibernate.event.DeleteEvent; import org.hibernate.event.def.DefaultDeleteEventListener; import org.hibernate.persister.entity.EntityPersister; @@ -34,4 +37,13 @@ return super.invokeDeleteLifecycle( session, entity, persister ); } + @Override + protected void performDetachedEntityDeletionCheck(DeleteEvent event) { + EventSource source = event.getSession(); + String entityName = event.getEntityName(); + EntityPersister persister = source.getEntityPersister( entityName, event.getObject() ); + Serializable id = persister.getIdentifier( event.getObject(), source.getEntityMode() ); + entityName = entityName == null ? source.guessEntityName( event.getObject() ) : entityName; + throw new IllegalArgumentException("Removing a detached instance "+ entityName + "#" + id); + } } Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/EntityManagerTest.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -11,7 +11,6 @@ import java.util.Map; import javax.persistence.EntityManager; import javax.persistence.FlushModeType; -import javax.persistence.PersistenceException; import javax.persistence.Query; import org.hibernate.FlushMode; @@ -105,7 +104,7 @@ assertTrue( em.contains( item ) ); em.getTransaction().begin(); - Item item1 = (Item) em.createQuery( "from Item where descr like 'M%'" ).getSingleResult(); + Item item1 = (Item) em.createQuery( "select i from Item i where descr like 'M%'" ).getSingleResult(); assertNotNull( item1 ); assertSame( item, item1 ); item.setDescr( "Micro$oft wireless mouse" ); @@ -124,7 +123,7 @@ assertSame( item, item1 ); assertTrue( em.contains( item ) ); - item1 = (Item) em.createQuery( "from Item where descr like 'M%'" ).getSingleResult(); + item1 = (Item) em.createQuery( "select i from Item i where descr like 'M%'" ).getSingleResult(); assertNotNull( item1 ); assertSame( item, item1 ); assertTrue( em.contains( item ) ); @@ -262,7 +261,7 @@ Query query = em.createQuery( "SELECT p FETCH JOIN p.distributors FROM Item p" ); query.getSingleResult(); } - catch (PersistenceException e) { + catch (IllegalArgumentException e) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream( stream ); out.writeObject( e ); @@ -271,7 +270,7 @@ stream.close(); ByteArrayInputStream byteIn = new ByteArrayInputStream( serialized ); ObjectInputStream in = new ObjectInputStream( byteIn ); - PersistenceException deserializedException = (PersistenceException) in.readObject(); + IllegalArgumentException deserializedException = (IllegalArgumentException) in.readObject(); in.close(); byteIn.close(); assertNull( deserializedException.getCause().getCause() ); Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/PackagedEntityManagerTest.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -261,7 +261,7 @@ assertTrue( em.contains( item ) ); em.getTransaction().begin(); - Item item1 = (Item) em.createQuery( "from Item where descr like 'M%'" ).getSingleResult(); + Item item1 = (Item) em.createQuery( "select i from Item i where descr like 'M%'" ).getSingleResult(); assertNotNull( item1 ); assertSame( item, item1 ); item.setDescr( "Micro$oft wireless mouse" ); @@ -280,7 +280,7 @@ assertSame( item, item1 ); assertTrue( em.contains( item ) ); - item1 = (Item) em.createQuery( "from Item where descr like 'M%'" ).getSingleResult(); + item1 = (Item) em.createQuery( "select i from Item i where descr like 'M%'" ).getSingleResult(); assertNotNull( item1 ); assertSame( item, item1 ); assertTrue( em.contains( item ) ); Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/callbacks/CallbackAndDirtyTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/callbacks/CallbackAndDirtyTest.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/callbacks/CallbackAndDirtyTest.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -46,11 +46,11 @@ manager.createQuery( "select p.address, p.name from Person p order by p.name" ).getResultList().size(), 3 ); - assertEquals( manager.createQuery( "from Person p where p.class = Customer" ).getResultList().size(), 1 ); + assertEquals( manager.createQuery( "select p from Person p where p.class = Customer" ).getResultList().size(), 1 ); manager.getTransaction().commit(); manager.getTransaction().begin(); - List customers = manager.createQuery( "from Customer c left join fetch c.salesperson" ).getResultList(); + List customers = manager.createQuery( "select c from Customer c left join fetch c.salesperson" ).getResultList(); for ( Iterator iter = customers.iterator(); iter.hasNext() ; ) { Customer c = (Customer) iter.next(); assertEquals( c.getSalesperson().getName(), "Mark" ); @@ -59,7 +59,7 @@ manager.getTransaction().commit(); manager.getTransaction().begin(); - customers = manager.createQuery( "from Customer" ).getResultList(); + customers = manager.createQuery( "select c from Customer c" ).getResultList(); for ( Iterator iter = customers.iterator(); iter.hasNext() ; ) { Customer c = (Customer) iter.next(); assertEquals( c.getSalesperson().getName(), "Mark" ); @@ -73,11 +73,11 @@ yomomma = manager.find( Person.class, new Long( ids[2] ) ); mark.setZip( "30306" ); - assertEquals( 1, manager.createQuery( "from Person p where p.zip = '30306'" ).getResultList().size() ); + assertEquals( 1, manager.createQuery( "select p from Person p where p.zip = '30306'" ).getResultList().size() ); manager.remove( mark ); manager.remove( joe ); manager.remove( yomomma ); - assertTrue( manager.createQuery( "from Person" ).getResultList().isEmpty() ); + assertTrue( manager.createQuery( "select p from Person p" ).getResultList().isEmpty() ); manager.getTransaction().commit(); manager.close(); } Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java 2006-06-09 01:25:55 UTC (rev 10002) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/ejb3configuration/EntityManagerSerializationTest.java 2006-06-09 01:31:32 UTC (rev 10003) @@ -68,7 +68,7 @@ em.getTransaction().begin(); item = em.find( Item.class, item.getName() ); item.setDescr( item.getDescr() + "-Amsterdam" ); - cat = (Cat) em.createQuery( "from " + Cat.class.getName() ).getSingleResult(); + cat = (Cat) em.createQuery( "select c from " + Cat.class.getName() + " c" ).getSingleResult(); cat.setLength( 34 ); em.flush(); em.remove( item ); |
From: <hib...@li...> - 2006-06-09 01:25:59
|
Author: epbernard Date: 2006-06-08 21:25:55 -0400 (Thu, 08 Jun 2006) New Revision: 10002 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java Log: fix NPE Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-06-08 21:08:04 UTC (rev 10001) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/reflection/java/EJB3OverridenAnnotationReader.java 2006-06-09 01:25:55 UTC (rev 10002) @@ -964,8 +964,9 @@ && ( super.isAnnotationPresent( Id.class ) || super.isAnnotationPresent( EmbeddedId.class ) ); //if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) { boolean mirrorAttributeIsId = defaults.canUseJavaAnnotations() && - ( mirroredAttribute.isAnnotationPresent(Id.class) - || mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ); + ( mirroredAttribute != null && + ( mirroredAttribute.isAnnotationPresent(Id.class) + || mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ) ); boolean propertyIsDefault = PropertyType.PROPERTY.equals( propertyType ) && ! mirrorAttributeIsId; return correctAccess || ( ! isExplicit && hasId ) || ( ! isExplicit && propertyIsDefault ); |
From: <hib...@li...> - 2006-06-08 21:08:55
|
Author: ste...@jb... Date: 2006-06-08 17:08:04 -0400 (Thu, 08 Jun 2006) New Revision: 10001 Modified: trunk/Hibernate3/grammar/hql-sql.g trunk/Hibernate3/grammar/hql.g trunk/Hibernate3/grammar/sql-gen.g Log: enums as constant literal in HQL Modified: trunk/Hibernate3/grammar/hql-sql.g =================================================================== --- trunk/Hibernate3/grammar/hql-sql.g 2006-06-08 21:04:45 UTC (rev 10000) +++ trunk/Hibernate3/grammar/hql-sql.g 2006-06-08 21:08:04 UTC (rev 10001) @@ -585,6 +585,7 @@ | NULL | TRUE { processBoolean(#constant); } | FALSE { processBoolean(#constant); } + | JAVA_CONSTANT ; literal Modified: trunk/Hibernate3/grammar/hql.g =================================================================== --- trunk/Hibernate3/grammar/hql.g 2006-06-08 21:04:45 UTC (rev 10000) +++ trunk/Hibernate3/grammar/hql.g 2006-06-08 21:08:04 UTC (rev 10001) @@ -130,6 +130,7 @@ NUM_DOUBLE; NUM_FLOAT; NUM_LONG; + JAVA_CONSTANT; } { Modified: trunk/Hibernate3/grammar/sql-gen.g =================================================================== --- trunk/Hibernate3/grammar/sql-gen.g 2006-06-08 21:04:45 UTC (rev 10000) +++ trunk/Hibernate3/grammar/sql-gen.g 2006-06-08 21:08:04 UTC (rev 10001) @@ -348,6 +348,7 @@ | NUM_LONG | QUOTED_STRING | CONSTANT + | JAVA_CONSTANT | TRUE | FALSE | IDENT |
From: <hib...@li...> - 2006-06-08 21:07:07
|
Author: ste...@jb... Date: 2006-06-08 17:04:45 -0400 (Thu, 08 Jun 2006) New Revision: 10000 Added: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/JavaConstantNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/QueryTranslatorImpl.java trunk/Hibernate3/src/org/hibernate/hql/ast/SqlASTFactory.java trunk/Hibernate3/src/org/hibernate/hql/ast/SqlGenerator.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BetweenOperatorNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/InLogicOperatorNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ParameterNode.java trunk/Hibernate3/src/org/hibernate/hql/ast/util/ASTUtil.java Log: enums as constant literal in HQL Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/QueryTranslatorImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/QueryTranslatorImpl.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/QueryTranslatorImpl.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -1,13 +1,6 @@ // $Id$ package org.hibernate.hql.ast; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - import antlr.ANTLRException; import antlr.RecognitionException; import antlr.TokenStreamException; @@ -38,17 +31,24 @@ import org.hibernate.hql.ast.tree.QueryNode; import org.hibernate.hql.ast.tree.Statement; import org.hibernate.hql.ast.util.ASTPrinter; +import org.hibernate.hql.ast.util.NodeTraverser; +import org.hibernate.hql.ast.util.ASTUtil; import org.hibernate.loader.hql.QueryLoader; import org.hibernate.persister.entity.Queryable; import org.hibernate.type.Type; import org.hibernate.util.IdentitySet; import org.hibernate.util.StringHelper; +import org.hibernate.util.ReflectHelper; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.ArrayList; + /** - * A QueryTranslator that uses an AST based parser. - * <br>User: josh - * <br>Date: Dec 31, 2003 - * <br>Time: 7:50:35 AM + * A QueryTranslator that uses an Antlr-based parser. * * @author Joshua Davis (pg...@so...) */ @@ -249,6 +249,10 @@ AST hqlAst = parser.getAST(); + JavaConstantConverter converter = new JavaConstantConverter(); + NodeTraverser walker = new NodeTraverser( converter ); + walker.traverseDepthFirst( hqlAst ); + showHqlAst( hqlAst ); parser.getParseErrorHandler().throwQueryException(); @@ -540,4 +544,34 @@ return paramTranslations; } + public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy { + private AST dotRoot; + public void visit(AST node) { + if ( dotRoot != null ) { + // we are already processing a dot-structure + if ( ASTUtil.isSubtreeChild( dotRoot, node ) ) { + // igndore it... + return; + } + else { + // we are now at a new tree level + dotRoot = null; + } + } + + if ( dotRoot == null && node.getType() == HqlTokenTypes.DOT ) { + dotRoot = node; + handleDotStructure( dotRoot ); + } + } + private void handleDotStructure(AST dotStructureRoot) { + String expression = ASTUtil.getPathText( dotStructureRoot ); + Object constant = ReflectHelper.getConstantValue( expression ); + if ( constant != null ) { + dotStructureRoot.setFirstChild( null ); + dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT ); + dotStructureRoot.setText( expression ); + } + } + } } Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/SqlASTFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/SqlASTFactory.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/SqlASTFactory.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -37,6 +37,8 @@ import org.hibernate.hql.ast.tree.BetweenOperatorNode; import org.hibernate.hql.ast.tree.UnaryLogicOperatorNode; import org.hibernate.hql.ast.tree.InLogicOperatorNode; +import org.hibernate.hql.ast.tree.JavaConstantNode; +import org.hibernate.hql.ast.tree.SessionFactoryAwareNode; import java.lang.reflect.Constructor; @@ -44,9 +46,8 @@ * Custom AST factory the intermediate tree that causes ANTLR to create specialized * AST nodes, given the AST node type (from HqlSqlTokenTypes). HqlSqlWalker registers * this factory with itself when it is initialized. - * <br>User: josh - * <br>Date: Nov 22, 2003 - * <br>Time: 3:34:28 PM + * + * @author Joshua */ public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes { private HqlSqlWalker walker; @@ -119,6 +120,8 @@ case TRUE: case FALSE: return LiteralNode.class; + case JAVA_CONSTANT: + return JavaConstantNode.class; case ORDER: return OrderByClause.class; case PLUS: @@ -189,6 +192,9 @@ InitializeableNode initializeableNode = ( InitializeableNode ) t; initializeableNode.initialize( walker ); } + if ( t instanceof SessionFactoryAwareNode ) { + ( ( SessionFactoryAwareNode ) t ).setSessionFactory( walker.getSessionFactoryHelper().getFactory() ); + } } /** Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/SqlGenerator.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/SqlGenerator.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/SqlGenerator.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -13,13 +13,13 @@ import org.hibernate.hql.antlr.SqlGeneratorBase; import org.hibernate.hql.ast.tree.MethodNode; import org.hibernate.hql.ast.tree.FromElement; -import org.hibernate.hql.ast.tree.ImpliedFromElement; +import org.hibernate.hql.ast.tree.JavaConstantNode; /** * Generates SQL by overriding callback methods in the base class, which does * the actual SQL AST walking. * - * @author josh Jun 23, 2004 6:49:55 AM + * @author Joshua */ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter { /** @@ -44,6 +44,15 @@ writer.clause( s ); } + protected void out(AST n) { + if ( n instanceof JavaConstantNode ) { + out( ( ( JavaConstantNode ) n ).getSqlText() ); + } + else { + super.out( n ); + } + } + protected void commaBetweenParameters(String comma) { writer.commaBetweenParameters( comma ); } Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BetweenOperatorNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BetweenOperatorNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BetweenOperatorNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -7,7 +7,7 @@ /** * Contract for nodes representing logcial BETWEEN (ternary) operators. * - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + * @author Steve Ebersole */ public class BetweenOperatorNode extends SqlNode implements OperatorNode { @@ -47,7 +47,7 @@ } private void check(Node check, Node first, Node second) { - if ( ParameterNode.class.isAssignableFrom( check.getClass() ) ) { + if ( ExpectedTypeAwareNode.class.isAssignableFrom( check.getClass() ) ) { Type expectedType = null; if ( SqlNode.class.isAssignableFrom( first.getClass() ) ) { expectedType = ( ( SqlNode ) first ).getDataType(); @@ -55,8 +55,7 @@ if ( expectedType == null && SqlNode.class.isAssignableFrom( second.getClass() ) ) { expectedType = ( ( SqlNode ) second ).getDataType(); } - ( ( ParameterNode ) check ).getHqlParameterSpecification().setExpectedType( expectedType ); - ( ( ParameterNode ) check ).setDataType( expectedType ); + ( ( ExpectedTypeAwareNode ) check ).setExpectedType( expectedType ); } } } Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -28,7 +28,7 @@ Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null; Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null; - if ( ParameterNode.class.isAssignableFrom( lhs.getClass() ) && rhType != null ) { + if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) && rhType != null ) { Type expectedType = null; // we have something like : "? [op] rhs" if ( isDateTimeType( rhType ) ) { @@ -42,7 +42,7 @@ else { expectedType = rhType; } - ( ( ParameterNode ) lhs ).getHqlParameterSpecification().setExpectedType( expectedType ); + ( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( expectedType ); } else if ( ParameterNode.class.isAssignableFrom( rhs.getClass() ) && lhType != null ) { Type expectedType = null; @@ -61,7 +61,7 @@ else { expectedType = lhType; } - ( ( ParameterNode ) rhs ).getHqlParameterSpecification().setExpectedType( expectedType ); + ( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( expectedType ); } } Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -7,7 +7,7 @@ /** * Contract for nodes representing binary operators. * - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + * @author Steve Ebersole */ public class BinaryLogicOperatorNode extends SqlNode implements BinaryOperatorNode { /** @@ -23,17 +23,13 @@ if ( rhs == null ) { throw new SemanticException( "right-hand operand of a binary operator was null" ); } - if ( ParameterNode.class.isAssignableFrom( lhs.getClass() ) + if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) && SqlNode.class.isAssignableFrom( rhs.getClass() ) ) { - ( ( ParameterNode ) lhs ).getHqlParameterSpecification().setExpectedType( - ( ( SqlNode ) rhs ).getDataType() - ); + ( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( ( ( SqlNode ) rhs ).getDataType() ); } - else if ( ParameterNode.class.isAssignableFrom( rhs.getClass() ) + else if ( ExpectedTypeAwareNode.class.isAssignableFrom( rhs.getClass() ) && SqlNode.class.isAssignableFrom( lhs.getClass() ) ) { - ( ( ParameterNode ) rhs ).getHqlParameterSpecification().setExpectedType( - ( ( SqlNode ) lhs ).getDataType() - ); + ( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( ( ( SqlNode ) lhs ).getDataType() ); } } Added: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -0,0 +1,14 @@ +package org.hibernate.hql.ast.tree; + +import org.hibernate.type.Type; + +/** + * Interface for nodes which wish to be made aware of any determined "expected + * type" based on the context within they appear in the query. + * + * @author Steve Ebersole + */ +public interface ExpectedTypeAwareNode { + public void setExpectedType(Type expectedType); + public Type getExpectedType(); +} Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/InLogicOperatorNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/InLogicOperatorNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/InLogicOperatorNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -5,7 +5,7 @@ import org.hibernate.type.Type; /** - * @author <a href="mailto:st...@hi...">Steve Ebersole </a> + * @author Steve Ebersole */ public class InLogicOperatorNode extends BinaryLogicOperatorNode implements BinaryOperatorNode { @@ -30,8 +30,8 @@ Type lhsType = ( ( SqlNode ) lhs ).getDataType(); AST inListChild = inList.getFirstChild(); while ( inListChild != null ) { - if ( ParameterNode.class.isAssignableFrom( inListChild.getClass() ) ) { - ( ( ParameterNode ) inListChild ).getHqlParameterSpecification().setExpectedType( lhsType ); + if ( ExpectedTypeAwareNode.class.isAssignableFrom( inListChild.getClass() ) ) { + ( ( ExpectedTypeAwareNode ) inListChild ).setExpectedType( lhsType ); } inListChild = inListChild.getNextSibling(); } Added: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/JavaConstantNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/JavaConstantNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/JavaConstantNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -0,0 +1,66 @@ +package org.hibernate.hql.ast.tree; + +import org.hibernate.type.Type; +import org.hibernate.type.TypeFactory; +import org.hibernate.type.LiteralType; +import org.hibernate.util.ReflectHelper; +import org.hibernate.util.StringHelper; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.dialect.Dialect; +import org.hibernate.QueryException; +import org.hibernate.hql.QueryTranslator; + +/** + * A node representing a static Java constant. + * + * @author Steve Ebersole + */ +public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, SessionFactoryAwareNode { + + private SessionFactoryImplementor factory; + + private String constantExpression; + private Object constantValue; + private Type heuristicType; + + private Type expectedType; + + public void setText(String s) { + // for some reason the antlr.CommonAST initialization routines force + // this method to get called twice. The first time with an empty string + if ( StringHelper.isNotEmpty( s ) ) { + constantExpression = s; + constantValue = ReflectHelper.getConstantValue( s ); + heuristicType = TypeFactory.heuristicType( constantValue.getClass().getName() ); + super.setText( s ); + } + } + + public void setExpectedType(Type expectedType) { + this.expectedType = expectedType; + } + + public Type getExpectedType() { + return expectedType; + } + + public void setSessionFactory(SessionFactoryImplementor factory) { + this.factory = factory; + } + + public String getSqlText() { + Type type = expectedType == null ? heuristicType : expectedType; + return resolveToLiteralString( type ); + } + + private String resolveToLiteralString(Type type) { + try { + LiteralType literalType = ( LiteralType ) type; + Dialect dialect = factory.getDialect(); + return literalType.objectToSQLString( constantValue, dialect ); + } + catch ( Throwable t ) { + throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + constantExpression, t ); + } + } +} Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ParameterNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ParameterNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/ParameterNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -2,13 +2,14 @@ package org.hibernate.hql.ast.tree; import org.hibernate.param.ParameterSpecification; +import org.hibernate.type.Type; /** * Implementation of ParameterNode. * * @author Steve Ebersole */ -public class ParameterNode extends HqlSqlWalkerNode implements DisplayableNode { +public class ParameterNode extends HqlSqlWalkerNode implements DisplayableNode, ExpectedTypeAwareNode { private ParameterSpecification parameterSpecification; public ParameterSpecification getHqlParameterSpecification() { @@ -22,4 +23,13 @@ public String getDisplayText() { return "{" + ( parameterSpecification == null ? "???" : parameterSpecification.renderDisplayInfo() ) + "}"; } + + public void setExpectedType(Type expectedType) { + getHqlParameterSpecification().setExpectedType( expectedType ); + setDataType( expectedType ); + } + + public Type getExpectedType() { + return getHqlParameterSpecification() == null ? null : getHqlParameterSpecification().getExpectedType(); + } } Added: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -0,0 +1,12 @@ +package org.hibernate.hql.ast.tree; + +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * Interface for nodes which require access to the SessionFactory + * + * @author Steve Ebersole + */ +public interface SessionFactoryAwareNode { + public void setSessionFactory(SessionFactoryImplementor sessionFactory); +} Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/util/ASTUtil.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/util/ASTUtil.java 2006-06-08 20:52:40 UTC (rev 9999) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/util/ASTUtil.java 2006-06-08 21:04:45 UTC (rev 10000) @@ -178,6 +178,48 @@ } /** + * Determine if a given node (test) is a direct (throtle to one level down) + * child of another given node (fixture). + * + * @param fixture The node against which to testto be checked for children. + * @param test The node to be tested as being a child of the parent. + * @return True if test is contained in the fixtures's direct children; + * false otherwise. + */ + public static boolean isDirectChild(AST fixture, AST test) { + AST n = fixture.getFirstChild(); + while ( n != null ) { + if ( n == test ) { + return true; + } + n = n.getNextSibling(); + } + return false; + } + + /** + * Determine if a given node (test) is contained anywhere in the subtree + * of another given node (fixture). + * + * @param fixture The node against which to testto be checked for children. + * @param test The node to be tested as being a subtree child of the parent. + * @return True if child is contained in the parent's collection of children. + */ + public static boolean isSubtreeChild(AST fixture, AST test) { + AST n = fixture.getFirstChild(); + while ( n != null ) { + if ( n == test ) { + return true; + } + if ( n.getFirstChild() != null && isSubtreeChild( n, test ) ) { + return true; + } + n = n.getNextSibling(); + } + return false; + } + + /** * Makes the child node a sibling of the parent, reconnecting all siblings. * * @param parent the parent |
From: <hib...@li...> - 2006-06-08 20:53:32
|
Author: ste...@jb... Date: 2006-06-08 16:52:40 -0400 (Thu, 08 Jun 2006) New Revision: 9999 Added: trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java trunk/Hibernate3/test/org/hibernate/test/hql/Animal.hbm.xml trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java Log: enums as constant literal in HQL Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-07 16:10:43 UTC (rev 9998) +++ trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-08 20:52:40 UTC (rev 9999) @@ -85,6 +85,17 @@ cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); } + + public void testJdkEnumStyleEnumConstant() throws Exception { + Session s = openSession(); + s.beginTransaction(); + + s.createQuery( "from Zoo z where z.classification = org.hibernate.test.hql.Classification.LAME" ).list(); + + s.getTransaction().commit(); + s.close(); + } + public void testParameterTypeMismatchFails() { Session s = openSession(); s.beginTransaction(); Modified: trunk/Hibernate3/test/org/hibernate/test/hql/Animal.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/Animal.hbm.xml 2006-06-07 16:10:43 UTC (rev 9998) +++ trunk/Hibernate3/test/org/hibernate/test/hql/Animal.hbm.xml 2006-06-08 20:52:40 UTC (rev 9999) @@ -107,7 +107,8 @@ </id> <discriminator column="zooType" type="character"/> <property name="name" type="string"/> - <map name="mammals"> + <property name="classification" type="org.hibernate.test.hql.ClassificationType"/> + <map name="mammals"> <key column="mammalZoo_id"/> <index type="string" column="name"/> <one-to-many class="Mammal"/> Added: trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-06-07 16:10:43 UTC (rev 9998) +++ trunk/Hibernate3/test/org/hibernate/test/hql/Classification.java 2006-06-08 20:52:40 UTC (rev 9999) @@ -0,0 +1,67 @@ +package org.hibernate.test.hql; + +import java.io.Serializable; +import java.util.HashMap; + +/** + * Mimic a JDK 5 enum. + * + * @author Steve Ebersole + */ +public class Classification implements Serializable, Comparable { + + public static final Classification COOL = new Classification( "COOL", 0 ); + public static final Classification LAME = new Classification( "LAME", 1 ); + + private static final HashMap INSTANCES = new HashMap(); + static { + INSTANCES.put( COOL.name, COOL ); + INSTANCES.put( LAME.name, LAME ); + } + + private final String name; + private final int ordinal; + private final int hashCode; + + private Classification(String name, int ordinal) { + this.name = name; + this.ordinal = ordinal; + + int hashCode = name.hashCode(); + hashCode = 29 * hashCode + ordinal; + this.hashCode = hashCode; + } + + public String name() { + return name; + } + + public int ordinal() { + return ordinal; + } + + public boolean equals(Object obj) { + return compareTo( obj ) == 0; + } + + public int compareTo(Object o) { + int otherOrdinal = ( ( Classification ) o ).ordinal; + if ( ordinal == otherOrdinal ) { + return 0; + } + else if ( ordinal > otherOrdinal ) { + return 1; + } + else { + return -1; + } + } + + public int hashCode() { + return hashCode; + } + + public static Classification valueOf(String name) { + return ( Classification ) INSTANCES.get( name ); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-06-07 16:10:43 UTC (rev 9998) +++ trunk/Hibernate3/test/org/hibernate/test/hql/ClassificationType.java 2006-06-08 20:52:40 UTC (rev 9999) @@ -0,0 +1,90 @@ +package org.hibernate.test.hql; + +import org.hibernate.usertype.UserType; +import org.hibernate.usertype.EnhancedUserType; +import org.hibernate.HibernateException; +import org.hibernate.Hibernate; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.PreparedStatement; +import java.sql.Types; +import java.io.Serializable; + +/** + * todo: describe ClassificationType + * + * @author Steve Ebersole + */ +public class ClassificationType implements EnhancedUserType { + + public int[] sqlTypes() { + return new int[] { Types.TINYINT }; + } + + public Class returnedClass() { + return Classification.class; + } + + public boolean equals(Object x, Object y) throws HibernateException { + if ( x == null && y == null ) { + return false; + } + else if ( x != null ) { + return x.equals( y ); + } + else { + return y.equals( x ); + } + } + + public int hashCode(Object x) throws HibernateException { + return x.hashCode(); + } + + public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { + String name = ( String ) Hibernate.STRING.nullSafeGet( rs, names[0] ); + return name == null ? null : Classification.valueOf( name ); + } + + public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { + String name = value == null ? null : ( ( Classification ) value ).name(); + Hibernate.STRING.nullSafeSet( st, name, index ); + } + + public Object deepCopy(Object value) throws HibernateException { + return value; + } + + public boolean isMutable() { + return false; + } + + public Serializable disassemble(Object value) throws HibernateException { + return ( Classification ) value; + } + + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return cached; + } + + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return original; + } + + public String objectToSQLString(Object value) { + return '\'' + extractName( value ) + '\''; + } + + public String toXMLString(Object value) { + return extractName( value ); + } + + public Object fromXMLString(String xmlValue) { + return Classification.valueOf( xmlValue ); + } + + private String extractName(Object obj) { + return ( ( Classification ) obj ).name(); + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-06-07 16:10:43 UTC (rev 9998) +++ trunk/Hibernate3/test/org/hibernate/test/hql/Zoo.java 2006-06-08 20:52:40 UTC (rev 9999) @@ -9,6 +9,7 @@ public class Zoo { private Long id; private String name; + private Classification classification; private Map animals; private Map mammals; private Address address; |
From: <hib...@li...> - 2006-06-07 16:11:00
|
Author: ste...@jb... Date: 2006-06-07 12:10:43 -0400 (Wed, 07 Jun 2006) New Revision: 9998 Modified: trunk/Hibernate3/test/org/hibernate/test/AllTests.java Log: ejb3 -> jpa Modified: trunk/Hibernate3/test/org/hibernate/test/AllTests.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-06-07 16:10:16 UTC (rev 9997) +++ trunk/Hibernate3/test/org/hibernate/test/AllTests.java 2006-06-07 16:10:43 UTC (rev 9998) @@ -130,9 +130,9 @@ import org.hibernate.test.version.db.DbVersionTest; import org.hibernate.test.version.sybase.SybaseTimestampVersioningTest; import org.hibernate.test.where.WhereTest; -import org.hibernate.test.ejb3.EJB3Suite; import org.hibernate.test.abstractembeddedcomponents.propertyref.AbstractComponentPropertyRefTest; import org.hibernate.test.abstractembeddedcomponents.cid.AbstractCompositeIdTest; +import org.hibernate.test.jpa.JPAComplianceSuite; import org.hibernate.dialect.Dialect; /** @@ -295,7 +295,7 @@ suite.addTest( TuplizerDynamicEntityTest.suite() ); suite.addTest( org.hibernate.test.bytecode.cglib.ReflectionOptimizerTest.suite() ); suite.addTest( org.hibernate.test.bytecode.javassist.ReflectionOptimizerTest.suite() ); - suite.addTest( EJB3Suite.suite() ); + suite.addTest( JPAComplianceSuite.suite() ); suite.addTest( AbstractComponentPropertyRefTest.suite() ); suite.addTest( AbstractCompositeIdTest.suite() ); |
From: <hib...@li...> - 2006-06-07 16:10:28
|
Author: ste...@jb... Date: 2006-06-07 12:10:16 -0400 (Wed, 07 Jun 2006) New Revision: 9997 Removed: trunk/Hibernate3/test/org/hibernate/test/ejb3/ Log: ejb3 -> jpa |
From: <hib...@li...> - 2006-06-07 15:30:07
|
Author: ste...@jb... Date: 2006-06-07 11:30:02 -0400 (Wed, 07 Jun 2006) New Revision: 9996 Added: trunk/Hibernate3/test/org/hibernate/test/jpa/ trunk/Hibernate3/test/org/hibernate/test/jpa/AbstractJPATest.java trunk/Hibernate3/test/org/hibernate/test/jpa/Item.hbm.xml trunk/Hibernate3/test/org/hibernate/test/jpa/Item.java trunk/Hibernate3/test/org/hibernate/test/jpa/JPAComplianceSuite.java trunk/Hibernate3/test/org/hibernate/test/jpa/Part.hbm.xml trunk/Hibernate3/test/org/hibernate/test/jpa/Part.java trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/ trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/FetchingTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.hbm.xml trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.java trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Stay.java trunk/Hibernate3/test/org/hibernate/test/jpa/lock/ trunk/Hibernate3/test/org/hibernate/test/jpa/lock/EJB3LockTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/lock/RepeatableReadTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/package.html trunk/Hibernate3/test/org/hibernate/test/jpa/proxy/ trunk/Hibernate3/test/org/hibernate/test/jpa/proxy/JPAProxyTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/ql/ trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/removed/ trunk/Hibernate3/test/org/hibernate/test/jpa/removed/RemovedEntityTest.java Log: ejb3 -> jpa Added: trunk/Hibernate3/test/org/hibernate/test/jpa/AbstractJPATest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/AbstractJPATest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/AbstractJPATest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,67 @@ +package org.hibernate.test.jpa; + +import org.hibernate.test.TestCase; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.proxy.EntityNotFoundDelegate; + +import java.io.Serializable; + +/** + * todo: describe AbstractJPATest + * + * @author Steve Ebersole + */ +public class AbstractJPATest extends TestCase { + public AbstractJPATest(String name) { + super( name ); + } + + protected String[] getMappings() { + return new String[] { "jpa/Part.hbm.xml", "jpa/Item.hbm.xml" }; + } + + protected void configure(Configuration cfg) { + super.configure( cfg ); + cfg.setProperty( Environment.JPAQL_STRICT_COMPLIANCE, "true" ); + cfg.setProperty( Environment.USE_SECOND_LEVEL_CACHE, "false" ); + cfg.setEntityNotFoundDelegate( new JPAEntityNotFoundDelegate() ); + } + + public String getCacheConcurrencyStrategy() { + // no second level caching + return null; + } + + private static class JPAEntityNotFoundDelegate implements EntityNotFoundDelegate { + public void handleEntityNotFound(String entityName, Serializable id) { + throw new EntityNotFoundException( entityName, id ); + } + } + + /** + * Mimic the JPA EntityNotFoundException. + */ + public static class EntityNotFoundException extends RuntimeException { + private final String entityName; + private final Serializable id; + + public EntityNotFoundException(String entityName, Serializable id) { + this( "unable to locate specified entity", entityName, id ); + } + + public EntityNotFoundException(String message, String entityName, Serializable id) { + super( message ); + this.entityName = entityName; + this.id = id; + } + + public String getEntityName() { + return entityName; + } + + public Serializable getId() { + return id; + } + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/Item.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/Item.hbm.xml 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/Item.hbm.xml 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,22 @@ +<?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.jpa"> + + <class name="Item" table="EJB3_ITEM"> + <id name="id" column="ITEM_ID" type="long"> + <generator class="increment"/> + </id> + <version name="version" column="VERS" type="long"/> + <property name="name" column="NAME" not-null="true"/> + <!-- modeled as many-to-one even though, yes, in real life would normally be many-to-many --> + <set name="parts" cascade="all" fetch="subselect" inverse="true"> + <key column="ITEM_ID"/> + <one-to-many class="Part"/> + </set> + </class> + +</hibernate-mapping> Added: trunk/Hibernate3/test/org/hibernate/test/jpa/Item.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/Item.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/Item.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,53 @@ +package org.hibernate.test.jpa; + +import java.util.Set; +import java.util.HashSet; + +/** + * @author Steve Ebersole + */ +public class Item { + private Long id; + private String name; + private long version; + private Set parts = new HashSet(); + + public Item() { + } + + public Item(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 long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public Set getParts() { + return parts; + } + + public void setParts(Set parts) { + this.parts = parts; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/JPAComplianceSuite.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/JPAComplianceSuite.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/JPAComplianceSuite.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,26 @@ +package org.hibernate.test.jpa; + +import junit.framework.Test; +import junit.framework.TestSuite; +import org.hibernate.test.jpa.lock.EJB3LockTest; +import org.hibernate.test.jpa.lock.RepeatableReadTest; +import org.hibernate.test.jpa.removed.RemovedEntityTest; +import org.hibernate.test.jpa.proxy.JPAProxyTest; +import org.hibernate.test.jpa.fetch.FetchingTest; +import org.hibernate.test.jpa.ql.JPAQLComplianceTest; + +/** + * @author Steve Ebersole + */ +public class JPAComplianceSuite { + public static Test suite() { + TestSuite suite = new TestSuite( "EJB3-compliance tests"); + suite.addTest( EJB3LockTest.suite() ); + suite.addTest( RepeatableReadTest.suite() ); + suite.addTest( JPAProxyTest.suite() ); + suite.addTest( FetchingTest.suite() ); + suite.addTest( JPAQLComplianceTest.suite() ); + suite.addTest( RemovedEntityTest.suite() ); + return suite; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/Part.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/Part.hbm.xml 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/Part.hbm.xml 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,19 @@ +<?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.jpa"> + + <class name="Part" table="EJB3_PART"> + <id name="id" column="PART_ID" type="long"> + <generator class="increment"/> + </id> + <many-to-one name="item" class="Item" column="ITEM_ID" cascade="save-update, lock" not-null="true"/> + <property name="name" column="NAME" not-null="true" type="string"/> + <property name="stockNumber" column="STOCK_NUM" not-null="true" type="string"/> + <property name="unitPrice" column="UNIT_PRICE" not-null="true" type="big_decimal"/> + </class> + +</hibernate-mapping> Added: trunk/Hibernate3/test/org/hibernate/test/jpa/Part.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/Part.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/Part.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,66 @@ +package org.hibernate.test.jpa; + +import java.math.BigDecimal; + +/** + * @author Steve Ebersole + */ +public class Part { + private Long id; + private Item item; + private String name; + private String stockNumber; + private BigDecimal unitPrice; + + public Part() { + } + + public Part(Item item, String name, String stockNumber, BigDecimal unitPrice) { + this.item = item; + this.name = name; + this.stockNumber = stockNumber; + this.unitPrice = unitPrice; + + this.item.getParts().add( this ); + } + + public Long getId() { + return id; + } + + private void setId(Long id) { + this.id = id; + } + + public Item getItem() { + return item; + } + + private void setItem(Item item) { + this.item = item; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStockNumber() { + return stockNumber; + } + + public void setStockNumber(String stockNumber) { + this.stockNumber = stockNumber; + } + + public BigDecimal getUnitPrice() { + return unitPrice; + } + + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/FetchingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/FetchingTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/FetchingTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,84 @@ +package org.hibernate.test.jpa.fetch; + +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.Hibernate; + +import java.util.Date; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Emmanuel Bernard + */ +public class FetchingTest extends AbstractJPATest { + + public void testLazy() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Person p = new Person( "Gavin", "King", "JBoss Inc" ); + Stay stay = new Stay( p, new Date(), new Date(), "A380", "Blah", "Blah" ); + p.addStay( stay ); + s.persist( p ); + tx.commit(); + s.clear(); + tx = s.beginTransaction(); + p = (Person) s.createQuery( "select p from Person p where p.firstName = :name" ) + .setParameter( "name", "Gavin" ).uniqueResult(); + assertFalse( Hibernate.isInitialized( p.getStays() ) ); + s.delete( p ); + tx.commit(); + s.close(); + } + + public void testHibernateFetchingLazy() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Person p = new Person( "Gavin", "King", "JBoss Inc" ); + Stay stay = new Stay( null, new Date(), new Date(), "A380", "Blah", "Blah" ); + Stay stay2 = new Stay( null, new Date(), new Date(), "A320", "Blah", "Blah" ); + Stay stay3 = new Stay( null, new Date(), new Date(), "A340", "Blah", "Blah" ); + stay.setOldPerson( p ); + stay2.setVeryOldPerson( p ); + stay3.setVeryOldPerson( p ); + p.addOldStay( stay ); + p.addVeryOldStay( stay2 ); + p.addVeryOldStay( stay3 ); + s.persist( p ); + tx.commit(); + s.clear(); + tx = s.beginTransaction(); + p = (Person) s.createQuery( "select p from Person p where p.firstName = :name" ) + .setParameter( "name", "Gavin" ).uniqueResult(); + assertFalse( Hibernate.isInitialized( p.getOldStays() ) ); + assertEquals( 1, p.getOldStays().size() ); + assertFalse( "lazy extra is failing", Hibernate.isInitialized( p.getOldStays() ) ); + s.clear(); + stay = (Stay) s.get( Stay.class, stay.getId() ); + assertTrue( ! Hibernate.isInitialized( stay.getOldPerson() ) ); + s.clear(); + stay3 = (Stay) s.get( Stay.class, stay3.getId() ); + assertTrue( "FetchMode.JOIN should overrides lazy options", Hibernate.isInitialized( stay3.getVeryOldPerson() ) ); + s.delete( stay3.getVeryOldPerson() ); + tx.commit(); + s.close(); + } + + public FetchingTest(String x) { + super( x ); + } + + protected String[] getMappings() { + return new String[] { "jpa/fetch/Person.hbm.xml" }; + } + + public static Test suite() { + return new TestSuite( FetchingTest.class ); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.hbm.xml 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.hbm.xml 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,48 @@ +<!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.jpa.fetch"> + + <class name="Person" table="PERSON"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <property name="firstName"/> + <property name="lastName"/> + <property name="companyName"/> + + <bag name="stays" cascade="all" lazy="true" inverse="true"> + <key column="PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + + <bag name="oldStays" cascade="all" lazy="extra" fetch="subselect" inverse="true"> + <key column="OLD_PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + + <bag name="veryOldStays" cascade="all" lazy="true" fetch="select" inverse="true"> + <key column="VERY_OLD_PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + </class> + + <class name="Stay" table="STAY"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + + <property name="startDate"/> + <property name="endDate"/> + <property name="vessel"/> + <property name="authoriser"/> + <property name="comments"/> + + <many-to-one name="person" column="PERS_ID" class="Person" cascade="all"/> + <many-to-one name="oldPerson" column="OLD_PERS_ID" class="Person" cascade="all" fetch="select"/> + <many-to-one name="veryOldPerson" column="VERY_OLD_PERS_ID" class="Person" cascade="all" fetch="join"/> + + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Person.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,136 @@ +package org.hibernate.test.jpa.fetch; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Date; +import java.util.ArrayList; + +/** + * Copied over from annotations test suite... + * + * @author Emmanuel Bernard + */ +public class Person implements Serializable { + + // member declaration + private Long id; + private String firstName; + private String lastName; + private String companyName; + private Collection stays; + private Collection oldStays; + private Collection veryOldStays; + + // constructors + public Person() { + } + + public Person(String firstName, String lastName, String companyName) { + this.firstName = firstName; + this.lastName = lastName; + this.companyName = companyName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public Collection getStays() { + return stays; + } + + public void setStays(Collection stays) { + this.stays = stays; + } + + public Collection getOldStays() { + return oldStays; + } + + public void setOldStays(Collection oldStays) { + this.oldStays = oldStays; + } + + public Collection getVeryOldStays() { + return veryOldStays; + } + + public void setVeryOldStays(Collection veryOldStays) { + this.veryOldStays = veryOldStays; + } + + + // business logic + public void addStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addStay( stay ); + } + + public void addStay(Stay stay) { + Collection stays = getStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.stays = stays; + } + + public void addOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addOldStay( stay ); + } + + public void addOldStay(Stay stay) { + Collection stays = getOldStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.oldStays = stays; + } + + public void addVeryOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addVeryOldStay( stay ); + } + + public void addVeryOldStay(Stay stay) { + Collection stays = getVeryOldStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.veryOldStays = stays; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Stay.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Stay.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/fetch/Stay.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,107 @@ +package org.hibernate.test.jpa.fetch; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author Emmanuel Bernard + */ +public class Stay implements Serializable { + + // member declaration + private Long id; + private Person person; + private Person oldPerson; + private Person veryOldPerson; + private Date startDate; + private Date endDate; + private String vessel; + private String authoriser; + private String comments; + + + // constructors + public Stay() { + } + + public Stay(Person person, Date startDate, Date endDate, String vessel, String authoriser, String comments) { + this.authoriser = authoriser; + this.endDate = endDate; + this.person = person; + this.startDate = startDate; + this.vessel = vessel; + this.comments = comments; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public Person getOldPerson() { + return oldPerson; + } + + public void setOldPerson(Person oldPerson) { + this.oldPerson = oldPerson; + } + + public Person getVeryOldPerson() { + return veryOldPerson; + } + + public void setVeryOldPerson(Person veryOldPerson) { + this.veryOldPerson = veryOldPerson; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public String getVessel() { + return vessel; + } + + public void setVessel(String vessel) { + this.vessel = vessel; + } + + public String getAuthoriser() { + return authoriser; + } + + public void setAuthoriser(String authoriser) { + this.authoriser = authoriser; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/lock/EJB3LockTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/lock/EJB3LockTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/lock/EJB3LockTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,179 @@ +package org.hibernate.test.jpa.lock; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.LockMode; +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.test.jpa.Item; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests specifically relating to section 3.3.5.3 [Lock Modes] of the + * JPA persistence specification (as of the <i>Proposed Final Draft</i>). + * + * @author Steve Ebersole + */ +public class EJB3LockTest extends AbstractJPATest { + public EJB3LockTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( EJB3LockTest.class ); + } + + /** + * Test the equivalent of EJB3 LockModeType.READ + * <p/> + * From the spec: + * <p/> + * If transaction T1 calls lock(entity, LockModeType.READ) on a versioned object, the entity + * manager must ensure that neither of the following phenomena can occur:<ul> + * <li>P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and + * obtains the modified value, before T1 has committed or rolled back. Transaction T2 eventually + * commits successfully; it does not matter whether T1 commits or rolls back and whether it does + * so before or after T2 commits. + * <li>P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or + * deletes that row, before T1 has committed. Both transactions eventually commit successfully. + * <p/> + * This will generally be achieved by the entity manager acquiring a lock on the underlying database row. + * Any such lock may be obtained immediately (so long as it is retained until commit completes), or the + * lock may be deferred until commit time (although even then it must be retained until the commit completes). + * Any implementation that supports repeatable reads in a way that prevents the above phenomena + * is permissible. + * <p/> + * The persistence implementation is not required to support calling lock(entity, LockMode-Type.READ) + * on a non-versioned object. When it cannot support such a lock call, it must throw the + * PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.READ + * must always prevent the phenomena P1 and P2. Applications that call lock(entity, LockModeType.READ) + * on non-versioned objects will not be portable. + * <p/> + * Odd as it may sound, EJB3 LockModeType.READ actually maps to the Hibernate LockMode.UPGRADE + */ + public void testLockModeTypeRead() { + if ( ! readCommittedIsolationMaintained( "ejb3 lock tests" ) ) { + return; + } + + final String initialName = "lock test"; + // set up some test data + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Item item = new Item(); + item.setName( initialName ); + s1.save( item ); + t1.commit(); + s1.close(); + + Long itemId = item.getId(); + + // perform the isolated update + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + item = ( Item ) s1.get( Item.class, itemId ); + s1.lock( item, LockMode.UPGRADE ); + item.setName( "updated" ); + s1.flush(); + + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Item item2 = ( Item ) s2.get( Item.class, itemId ); + assertEquals( "isolation not maintained", initialName, item2.getName() ); + + t1.commit(); + s1.close(); + + item2 = ( Item ) s2.get( Item.class, itemId ); + assertEquals( "repeatable read not maintained", initialName, item2.getName() ); + t2.commit(); + s2.close(); + + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + s1.delete( item ); + t1.commit(); + s1.close(); + } + + /** + * Test the equivalent of EJB3 LockModeType.WRITE + * <p/> + * From the spec: + * <p/> + * If transaction T1 calls lock(entity, LockModeType.WRITE) on a versioned object, the entity + * manager must avoid the phenomena P1 and P2 (as with LockModeType.READ) and must also force + * an update (increment) to the entity's version column. A forced version update may be performed immediately, + * or may be deferred until a flush or commit. If an entity is removed before a deferred version + * update was to have been applied, the forced version update is omitted, since the underlying database + * row no longer exists. + * <p/> + * The persistence implementation is not required to support calling lock(entity, LockMode-Type.WRITE) + * on a non-versioned object. When it cannot support a such lock call, it must throw the + * PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.WRITE + * must always prevent the phenomena P1 and P2. For non-versioned objects, whether or + * not LockModeType.WRITE has any additional behaviour is vendor-specific. Applications that call + * lock(entity, LockModeType.WRITE) on non-versioned objects will not be portable. + * <p/> + * Due to the requirement that LockModeType.WRITE needs to force a version increment, + * a new Hibernate LockMode was added to support this behavior: {@link org.hibernate.LockMode#FORCE}. + */ + public void testLockModeTypeWrite() { + if ( ! readCommittedIsolationMaintained( "ejb3 lock tests" ) ) { + return; + } + final String initialName = "lock test"; + // set up some test data + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Item item = new Item(); + item.setName( initialName ); + s1.save( item ); + t1.commit(); + s1.close(); + + Long itemId = item.getId(); + long initialVersion = item.getVersion(); + + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + item = ( Item ) s1.get( Item.class, itemId ); + s1.lock( item, LockMode.FORCE ); + assertEquals( "no forced version increment", initialVersion + 1, item.getVersion() ); + + s1.lock( item, LockMode.FORCE ); + assertEquals( "subsequent LockMode.FORCE did not no-op", initialVersion + 1, item.getVersion() ); + + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Item item2 = ( Item ) s2.get( Item.class, itemId ); + assertEquals( "isolation not maintained", initialName, item2.getName() ); + + item.setName( "updated-1" ); + s1.flush(); + // currently an unfortunate side effect... + assertEquals( initialVersion + 2, item.getVersion() ); + + t1.commit(); + s1.close(); + + item2.setName( "updated" ); + try { + t2.commit(); + fail( "optimisitc lock should have failed" ); + } + catch( Throwable ignore ) { + // expected behavior + t2.rollback(); + } + finally { + s2.close(); + } + + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + s1.delete( item ); + t1.commit(); + s1.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/lock/RepeatableReadTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/lock/RepeatableReadTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/lock/RepeatableReadTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,216 @@ +package org.hibernate.test.jpa.lock; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.LockMode; +import org.hibernate.StaleObjectStateException; +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.test.jpa.Item; +import org.hibernate.test.jpa.Part; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.math.BigDecimal; + +/** + * Test that the Hibernate Session complies with REPEATABLE_READ isolation + * semantics. + * + * @author Steve Ebersole + */ +public class RepeatableReadTest extends AbstractJPATest { + + public RepeatableReadTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( org.hibernate.test.jpa.lock.RepeatableReadTest.class ); + } + + + // versioned entity tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public void testStaleVersionedInstanceFoundInQueryResult() { + String check = "EJB3 Specification"; + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Item item = new Item( check ); + s1.save( item ); + t1.commit(); + s1.close(); + + Long itemId = item.getId(); + long initialVersion = item.getVersion(); + + // Now, open a new Session and re-load the item... + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + item = ( Item ) s1.get( Item.class, itemId ); + + // now that the item is associated with the persistence-context of that session, + // open a new session and modify it "behind the back" of the first session + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Item item2 = ( Item ) s2.get( Item.class, itemId ); + item2.setName( "EJB3 Persistence Spec" ); + t2.commit(); + s2.close(); + + // at this point, s1 now contains stale data, so try an hql query which + // returns said item and make sure we get the previously associated state + // (i.e., the old name and the old version) + item2 = ( Item ) s1.createQuery( "select i from Item i" ).list().get( 0 ); + assertTrue( item == item2 ); + assertEquals( "encountered non-repeatable read", check, item2.getName() ); + assertEquals( "encountered non-repeatable read", initialVersion, item2.getVersion() ); + + // clean up + s1.createQuery( "delete Item" ).executeUpdate(); + t1.commit(); + s1.close(); + } + + public void testStaleVersionedInstanceFoundOnLock() { + if ( ! readCommittedIsolationMaintained( "repeatable read tests" ) ) { + return; + } + String check = "EJB3 Specification"; + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Item item = new Item( check ); + s1.save( item ); + t1.commit(); + s1.close(); + + Long itemId = item.getId(); + long initialVersion = item.getVersion(); + + // Now, open a new Session and re-load the item... + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + item = ( Item ) s1.get( Item.class, itemId ); + + // now that the item is associated with the persistence-context of that session, + // open a new session and modify it "behind the back" of the first session + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Item item2 = ( Item ) s2.get( Item.class, itemId ); + item2.setName( "EJB3 Persistence Spec" ); + t2.commit(); + s2.close(); + + // at this point, s1 now contains stale data, so acquire a READ lock + // and make sure we get the already associated state (i.e., the old + // name and the old version) + s1.lock( item, LockMode.READ ); + item2 = ( Item ) s1.get( Item.class, itemId ); + assertTrue( item == item2 ); + assertEquals( "encountered non-repeatable read", check, item2.getName() ); + assertEquals( "encountered non-repeatable read", initialVersion, item2.getVersion() ); + + // attempt to acquire an UPGRADE lock; this should fail + try { + s1.lock( item, LockMode.UPGRADE ); + fail( "expected UPGRADE lock failure" ); + } + catch( StaleObjectStateException expected ) { + // this is the expected behavior + } + + // clean up + s1.createQuery( "delete Item" ).executeUpdate(); + t1.commit(); + s1.close(); + } + + + // non-versioned entity tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public void testStaleNonVersionedInstanceFoundInQueryResult() { + String check = "Lock Modes"; + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Part part = new Part( new Item( "EJB3 Specification" ), check, "3.3.5.3", new BigDecimal( 0.0 ) ); + s1.save( part ); + t1.commit(); + s1.close(); + + Long partId = part.getId(); + + // Now, open a new Session and re-load the part... + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + part = ( Part ) s1.get( Part.class, partId ); + + // now that the item is associated with the persistence-context of that session, + // open a new session and modify it "behind the back" of the first session + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Part part2 = ( Part ) s2.get( Part.class, partId ); + part2.setName( "Lock Mode Types" ); + t2.commit(); + s2.close(); + + // at this point, s1 now contains stale data, so try an hql query which + // returns said part and make sure we get the previously associated state + // (i.e., the old name) + part2 = ( Part ) s1.createQuery( "select p from Part p" ).list().get( 0 ); + assertTrue( part == part2 ); + assertEquals( "encountered non-repeatable read", check, part2.getName() ); + + // clean up + s1.delete( part ); + t1.commit(); + s1.close(); + } + + public void testStaleNonVersionedInstanceFoundOnLock() { + if ( ! readCommittedIsolationMaintained( "repeatable read tests" ) ) { + return; + } + String check = "Lock Modes"; + Session s1 = getSessions().openSession(); + Transaction t1 = s1.beginTransaction(); + Part part = new Part( new Item( "EJB3 Specification" ), check, "3.3.5.3", new BigDecimal( 0.0 ) ); + s1.save( part ); + t1.commit(); + s1.close(); + + Long partId = part.getId(); + + // Now, open a new Session and re-load the part... + s1 = getSessions().openSession(); + t1 = s1.beginTransaction(); + part = ( Part ) s1.get( Part.class, partId ); + + // now that the item is associated with the persistence-context of that session, + // open a new session and modify it "behind the back" of the first session + Session s2 = getSessions().openSession(); + Transaction t2 = s2.beginTransaction(); + Part part2 = ( Part ) s2.get( Part.class, partId ); + part2.setName( "Lock Mode Types" ); + t2.commit(); + s2.close(); + + // at this point, s1 now contains stale data, so acquire a READ lock + // and make sure we get the already associated state (i.e., the old + // name and the old version) + s1.lock( part, LockMode.READ ); + part2 = ( Part ) s1.get( Part.class, partId ); + assertTrue( part == part2 ); + assertEquals( "encountered non-repeatable read", check, part2.getName() ); + + // then acquire an UPGRADE lock; this should fail + s1.lock( part, LockMode.UPGRADE ); + part2 = ( Part ) s1.get( Part.class, partId ); + assertTrue( part == part2 ); + assertEquals( "encountered non-repeatable read", check, part2.getName() ); + + // clean up +// s1.refresh( item ); + s1.delete( part ); + t1.commit(); + s1.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/package.html =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/package.html 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/package.html 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,9 @@ +<html> + <head></head> + <body> + <p> + Tests for any JPA-specific behavior for which we need to ensure + compliance. + </p> + </body> +</html> Added: trunk/Hibernate3/test/org/hibernate/test/jpa/proxy/JPAProxyTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/proxy/JPAProxyTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/proxy/JPAProxyTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,98 @@ +package org.hibernate.test.jpa.proxy; + +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.test.jpa.Item; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.Hibernate; +import junit.framework.Test; +import junit.framework.TestSuite; +import junit.framework.AssertionFailedError; + +/** + * Test relation between proxies and get()/load() processing + * and make sure the interactions match the ejb3 expectations + * + * @author Steve Ebersole + */ +public class JPAProxyTest extends AbstractJPATest { + public JPAProxyTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( JPAProxyTest.class ); + } + + public void testEjb3ProxyUsage() { + Session s = openSession(); + Transaction txn = s.beginTransaction(); + + Item item = ( Item ) s.load( Item.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( item ) ); + try { + Hibernate.initialize( item ); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent proxy access : " + t ); + } + + s.clear(); + + Item item2 = ( Item ) s.load( Item.class, new Long(-1) ); + assertFalse( Hibernate.isInitialized( item2 ) ); + assertFalse( item == item2 ); + try { + item2.getName(); + fail( "proxy access did not fail on non-existent proxy" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent proxy access : " + t ); + } + + txn.commit(); + s.close(); + } + + /** + * The ejb3 find() method maps to the Hibernate get() method + */ + public void testGetSemantics() { + Long nonExistentId = new Long( -1 ); + Session s = openSession(); + Transaction txn = s.beginTransaction(); + Item item = ( Item ) s.get( Item.class, nonExistentId ); + assertNull( "get() of non-existent entity did not return null", item ); + txn.commit(); + s.close(); + + s = openSession(); + txn = s.beginTransaction(); + // first load() it to generate a proxy... + item = ( Item ) s.load( Item.class, nonExistentId ); + assertFalse( Hibernate.isInitialized( item ) ); + // then try to get() it to make sure we get an exception + try { + s.get( Item.class, nonExistentId ); + fail( "force load did not fail on non-existent entity" ); + } + catch ( EntityNotFoundException e ) { + // expected behavior + } + catch( AssertionFailedError e ) { + throw e; + } + catch ( Throwable t ) { + fail( "unexpected exception type on non-existent entity force load : " + t ); + } + txn.commit(); + s.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/ql/JPAQLComplianceTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,34 @@ +package org.hibernate.test.jpa.ql; + +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.Session; +import org.hibernate.hql.ast.QuerySyntaxException; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests for various JPAQL compliance issues + * + * @author Steve Ebersole + */ +public class JPAQLComplianceTest extends AbstractJPATest { + public JPAQLComplianceTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( JPAQLComplianceTest.class ); + } + + public void testNoSelectClause() { + Session s = openSession(); + try { + s.createQuery( "from Part" ).list(); + fail( "expecting parse failure" ); + } + catch( QuerySyntaxException qe ) { + // expected behavior + } + s.close(); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/removed/RemovedEntityTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/removed/RemovedEntityTest.java 2006-06-06 20:51:29 UTC (rev 9995) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/removed/RemovedEntityTest.java 2006-06-07 15:30:02 UTC (rev 9996) @@ -0,0 +1,61 @@ +package org.hibernate.test.jpa.removed; + +import org.hibernate.test.jpa.AbstractJPATest; +import org.hibernate.test.jpa.Item; +import org.hibernate.Session; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * + * @author Steve Ebersole + */ +public class RemovedEntityTest extends AbstractJPATest { + public RemovedEntityTest(String name) { + super( name ); + } + + public static Test suite() { + return new TestSuite( RemovedEntityTest.class ); + } + + public void testRemoveThenContains() { + Session s = openSession(); + s.beginTransaction(); + Item item = new Item(); + item.setName( "dummy" ); + s.persist( item ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + s.delete( item ); + boolean contains = s.contains( item ); + s.getTransaction().commit(); + s.close(); + + assertFalse( "expecting removed entity to not be contained", contains ); + } + + public void testRemoveThenGet() { + Session s = openSession(); + s.beginTransaction(); + Item item = new Item(); + item.setName( "dummy" ); + s.persist( item ); + s.getTransaction().commit(); + s.close(); + + Long id = item.getId(); + + s = openSession(); + s.beginTransaction(); + s.delete( item ); + item = ( Item ) s.get( Item.class, id ); + s.getTransaction().commit(); + s.close(); + + assertNull( "expecting removed entity to be returned as null from get()", item ); + } +} |
From: Learn 'N E. <ho...@gr...> - 2006-06-07 05:34:26
|
Hello Friend, Build Your OWN Six Fig-ure In-co-me! This Is not the same old pro-grams You have seen before.... ==>>> http://yep.it/?k1c5b9 This pro-gram could create high level of weal-th for many people. You probably knew that someone, somewhere would eventually come along with an idea and build something never seen before. It looks good and cool program! It pays 100% on payplan, just visit the site and see your potential income. We could have a great income while having fun at the same time. Here is our cool site: =>>> http://yep.it/?k1c5b9 <<<= Have a Great Day! Best Regard, -Netprofit Team http://yep.it/?k1c5b9 ***~***~***~***~***~***~***~***~***~***~***~***~*** P.S. If the site didn't work please let me know. Thank You! |
From: <hib...@li...> - 2006-06-06 20:52:08
|
Author: ste...@jb... Date: 2006-06-06 16:51:29 -0400 (Tue, 06 Jun 2006) New Revision: 9995 Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java Log: HHH-1818 : changed behavior of contains(), load(), and get() after entity has been remove()ed Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java 2006-06-06 20:48:37 UTC (rev 9994) +++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultLoadEventListener.java 2006-06-06 20:51:29 UTC (rev 9995) @@ -11,6 +11,7 @@ import org.hibernate.ObjectDeletedException; import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; +import org.hibernate.EntityMode; import org.hibernate.cache.CacheConcurrencyStrategy; import org.hibernate.cache.CacheKey; import org.hibernate.cache.entry.CacheEntry; @@ -72,12 +73,19 @@ ); } - Class idClass = persister.getIdentifierType().getReturnedClass(); - if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) { - throw new TypeMismatchException( - "Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass() - ); + if ( persister.getIdentifierType().isComponentType() && EntityMode.DOM4J == event.getSession().getEntityMode() ) { + // skip this check for composite-ids relating to dom4j entity-mode; + // alternatively, we could add a check to make sure the incoming id value is + // an instance of Element... } + else { + Class idClass = persister.getIdentifierType().getReturnedClass(); + if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) { + throw new TypeMismatchException( + "Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass() + ); + } + } EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode() ); @@ -228,18 +236,21 @@ final LoadEventListener.LoadType options, final PersistenceContext persistenceContext ) { - Object existing = persistenceContext.getEntity(keyToLoad); + Object existing = persistenceContext.getEntity( keyToLoad ); if ( existing != null ) { // return existing object or initialized proxy (unless deleted) - log.trace("entity found in session cache"); + log.trace( "entity found in session cache" ); if ( options.isCheckDeleted() ) { - EntityEntry entry = persistenceContext.getEntry(existing); - throwObjectDeletedIfNecessary(event, entry); + EntityEntry entry = persistenceContext.getEntry( existing ); + Status status = entry.getStatus(); + if ( status == Status.DELETED || status == Status.GONE ) { + return null; + } } return existing; } else { - log.trace("creating new proxy for entity"); + log.trace( "creating new proxy for entity" ); // return new uninitialized proxy Object proxy = persister.createProxy( event.getEntityId(), event.getSession() ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); @@ -295,6 +306,7 @@ return proxy; } + protected static final Object REMOVED_ENTITY_MARKER = new Object(); /** * Coordinates the efforts to load a given entity. First, an attempt is @@ -320,6 +332,10 @@ } Object entity = loadFromSessionCache(event, keyToLoad, options); + if ( entity == REMOVED_ENTITY_MARKER ) { + log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" ); + return null; + } if ( entity != null ) { if ( log.isTraceEnabled() ) { log.trace( @@ -409,29 +425,21 @@ throws HibernateException { SessionImplementor session = event.getSession(); - Object old = session.getEntityUsingInterceptor(keyToLoad); + Object old = session.getEntityUsingInterceptor( keyToLoad ); if ( old != null ) { // this object was already loaded - EntityEntry oldEntry = session.getPersistenceContext().getEntry(old); + EntityEntry oldEntry = session.getPersistenceContext().getEntry( old ); if ( options.isCheckDeleted() ) { - throwObjectDeletedIfNecessary( event, oldEntry ); + Status status = oldEntry.getStatus(); + if ( status == Status.DELETED || status == Status.GONE ) { + return REMOVED_ENTITY_MARKER; + } } upgradeLock( old, oldEntry, event.getLockMode(), session ); } return old; } - private void throwObjectDeletedIfNecessary(LoadEvent event, EntityEntry oldEntry) { - Status status = oldEntry.getStatus(); - if ( status == Status.DELETED || status == Status.GONE ) { - throw new ObjectDeletedException( - "The object with that id was deleted", - event.getEntityId(), - event.getEntityClassName() - ); - } - } - /** * Attempts to load the entity from the second-level cache. * Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-06-06 20:48:37 UTC (rev 9994) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-06-06 20:51:29 UTC (rev 9995) @@ -1612,7 +1612,11 @@ object = li.getImplementation(); } } - return persistenceContext.isEntryFor(object); + // A session is considered to contain an entity only if the entity has + // an entry in the session's persistence context and the entry reports + // that the entity has not been removed + EntityEntry entry = persistenceContext.getEntry( object ); + return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE; } public Query createQuery(String queryString) { |
From: <hib...@li...> - 2006-06-06 20:49:10
|
Author: ste...@jb... Date: 2006-06-06 16:48:37 -0400 (Tue, 06 Jun 2006) New Revision: 9994 Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/MasterDetailTest.java Log: HQL count(*) return type Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/MasterDetailTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/MasterDetailTest.java 2006-06-06 20:47:25 UTC (rev 9993) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/MasterDetailTest.java 2006-06-06 20:48:37 UTC (rev 9994) @@ -411,7 +411,7 @@ assertTrue( s.createFilter( master.getDetails(), "select max(this.i)" ).iterate().next() instanceof Integer ); assertTrue( s.createFilter( master.getDetails(), "select max(this.i) group by this.id" ).iterate().next() instanceof Integer ); - assertTrue( s.createFilter( master.getDetails(), "select count(*)" ).iterate().next() instanceof Integer ); + assertTrue( s.createFilter( master.getDetails(), "select count(*)" ).iterate().next() instanceof Long ); assertTrue( s.createFilter( master.getDetails(), "select this.master" ).list().size()==2 ); assertTrue( s.filter( master.getMoreDetails(), "" ).size()==0 ); |
From: <hib...@li...> - 2006-06-06 20:47:59
|
Author: ste...@jb... Date: 2006-06-06 16:47:25 -0400 (Tue, 06 Jun 2006) New Revision: 9993 Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/FooBarTest.java Log: changed expected exception types for change in load after delete behavior Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/FooBarTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/FooBarTest.java 2006-06-06 20:46:18 UTC (rev 9992) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/FooBarTest.java 2006-06-06 20:47:25 UTC (rev 9993) @@ -4296,7 +4296,7 @@ try { s.load(Foo.class, id); } - catch (ObjectDeletedException ode) { + catch (ObjectNotFoundException ode) { err=true; } assertTrue(err); @@ -4318,7 +4318,7 @@ try { s.load(Fo.class, id); } - catch (ObjectDeletedException ode) { + catch (ObjectNotFoundException ode) { err=true; } assertTrue(err); |
From: <hib...@li...> - 2006-06-06 20:47:18
|
Author: ste...@jb... Date: 2006-06-06 16:46:18 -0400 (Tue, 06 Jun 2006) New Revision: 9992 Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/CustomPersister.java Log: fixed broken getIdentifierType() impl Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/CustomPersister.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/CustomPersister.java 2006-06-06 20:45:22 UTC (rev 9991) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/CustomPersister.java 2006-06-06 20:46:18 UTC (rev 9992) @@ -409,7 +409,7 @@ * @see EntityPersister#getIdentifierType() */ public Type getIdentifierType() { - return Hibernate.LONG; + return Hibernate.STRING; } /** |
From: <hib...@li...> - 2006-06-06 20:45:55
|
Author: ste...@jb... Date: 2006-06-06 16:45:22 -0400 (Tue, 06 Jun 2006) New Revision: 9991 Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java Log: add ordering to query to avoid test assertion sensitivity on db-dependent return order Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-06 18:08:00 UTC (rev 9990) +++ trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-06-06 20:45:22 UTC (rev 9991) @@ -1278,9 +1278,9 @@ session = openSession(); - results = session.createQuery( "select a from Animal a, Animal b" ) - .setResultTransformer(new DistinctRootEntityResultTransformer()) - .list(); + results = session.createQuery( "select a from Animal a, Animal b order by a.id" ) + .setResultTransformer(new DistinctRootEntityResultTransformer()) + .list(); assertEquals( "Incorrect result size", 2, results.size()); assertTrue( "Incorrect return type", results.get(0) instanceof Animal ); firstAnimal = (Animal) results.get(0); |
From: <hib...@li...> - 2006-06-06 18:38:06
|
Author: ste...@jb... Date: 2006-06-06 14:08:00 -0400 (Tue, 06 Jun 2006) New Revision: 9990 Modified: trunk/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java Log: temporary ddl operations and transactions Modified: trunk/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java 2006-06-06 17:21:38 UTC (rev 9989) +++ trunk/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java 2006-06-06 18:08:00 UTC (rev 9990) @@ -13,7 +13,12 @@ /** * Class which provides the isolation semantics required by - * an {@link IsolatedWork}. + * an {@link IsolatedWork}. Processing comes in two flavors:<ul> + * <li>{@link #doIsolatedWork} : makes sure the work to be done is + * performed in a seperate, distinct transaction</li> + * <li>{@link #doNonTransactedWork} : makes sure the work to be + * done is performed outside the scope of any transaction</li> + * </ul> * * @author Steve Ebersole */ @@ -22,8 +27,8 @@ private static final Log log = LogFactory.getLog( Isolater.class ); /** - * The exposed service of this class. Ensures that all work actually - * performed by the given work will occur on a seperate transaction. + * Ensures that all processing actually performed by the given work will + * occur on a seperate transaction. * * @param work The work to be performed. * @param session The session from which this request is originating. @@ -32,19 +37,37 @@ public static void doIsolatedWork(IsolatedWork work, SessionImplementor session) throws HibernateException { boolean isJta = session.getFactory().getTransactionManager() != null; if ( isJta ) { - new JtaDelegate( session ).delegateWork( work ); + new JtaDelegate( session ).delegateWork( work, true ); } else { - new JdbcDelegate( session ).delegateWork( work ); + new JdbcDelegate( session ).delegateWork( work, true ); } } + /** + * Ensures that all processing actually performed by the given work will + * occur outside of a transaction. + * + * @param work The work to be performed. + * @param session The session from which this request is originating. + * @throws HibernateException + */ + public static void doNonTransactedWork(IsolatedWork work, SessionImplementor session) throws HibernateException { + boolean isJta = session.getFactory().getTransactionManager() != null; + if ( isJta ) { + new JtaDelegate( session ).delegateWork( work, false ); + } + else { + new JdbcDelegate( session ).delegateWork( work, false ); + } + } + // should be ok performance-wise to generate new delegate instances for each // request since these are locally stack-scoped. Besides, it makes the code // much easier to read than the old TransactionHelper stuff... private static interface Delegate { - public void delegateWork(IsolatedWork work) throws HibernateException; + public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException; } /** @@ -59,7 +82,7 @@ this.session = session; } - public void delegateWork(IsolatedWork work) throws HibernateException { + public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException { TransactionManager transactionManager = session.getFactory().getTransactionManager(); Transaction surroundingTransaction = null; Connection connection = null; @@ -72,7 +95,11 @@ if ( log.isDebugEnabled() ) { log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" ); } - transactionManager.begin(); + + if ( transacted ) { + transactionManager.begin(); + } + connection = session.getBatcher().openConnection(); // perform the actual work @@ -81,7 +108,10 @@ // if everything went ok, commit the transaction and close the obtained // connection handle... session.getBatcher().closeConnection( connection ); - transactionManager.commit(); + + if ( transacted ) { + transactionManager.commit(); + } } catch( Throwable t ) { // at some point the processing went bad, so we need to: @@ -96,13 +126,14 @@ catch( Throwable ignore ) { log.trace( "unable to release connection on exception [" + ignore + "]" ); } - try { - transactionManager.rollback(); + if ( transacted ) { + try { + transactionManager.rollback(); + } + catch( Throwable ignore ) { + log.trace( "unable to rollback new transaction on exception [" + ignore + "]" ); + } } - catch( Throwable ignore ) { - log.trace( "unable to rollback new transaction on exception [" + ignore + "]" ); - } - // finally handle the exception if ( t instanceof HibernateException ) { throw ( HibernateException ) t; @@ -140,23 +171,28 @@ this.session = session; } - public void delegateWork(IsolatedWork work) throws HibernateException { + public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException { Connection connection = null; boolean wasAutoCommit = false; try { connection = session.getBatcher().openConnection(); - if ( connection.getAutoCommit() ) { - wasAutoCommit = true; - connection.setAutoCommit( false ); + + if ( transacted ) { + if ( connection.getAutoCommit() ) { + wasAutoCommit = true; + connection.setAutoCommit( false ); + } } work.doWork( connection ); - connection.commit(); + if ( transacted ) { + connection.commit(); + } } catch( Throwable t ) { try { - if ( connection!= null && !connection.isClosed() ) { + if ( transacted && connection != null && !connection.isClosed() ) { connection.rollback(); } } @@ -179,7 +215,7 @@ } } finally { - if ( wasAutoCommit ) { + if ( transacted && wasAutoCommit ) { try { connection.setAutoCommit( true ); } |
From: <hib...@li...> - 2006-06-06 17:23:30
|
Author: ste...@jb... Date: 2006-06-06 13:21:38 -0400 (Tue, 06 Jun 2006) New Revision: 9989 Modified: trunk/Hibernate3/src/org/hibernate/cfg/Environment.java trunk/Hibernate3/src/org/hibernate/cfg/Settings.java trunk/Hibernate3/src/org/hibernate/cfg/SettingsFactory.java trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SelectClause.java trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java Log: HHH-1817 : JPA-QL compliance setting Modified: trunk/Hibernate3/src/org/hibernate/cfg/Environment.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -455,6 +455,7 @@ public static final String BYTECODE_PROVIDER = "hibernate.bytecode.provider"; + public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance"; private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE; private static final boolean ENABLE_BINARY_STREAMS; Modified: trunk/Hibernate3/src/org/hibernate/cfg/Settings.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Settings.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/cfg/Settings.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -14,7 +14,6 @@ import org.hibernate.exception.SQLExceptionConverter; import org.hibernate.EntityMode; import org.hibernate.ConnectionReleaseMode; -import org.hibernate.bytecode.BytecodeProvider; /** * Settings that affect the behaviour of Hibernate at runtime. @@ -63,17 +62,26 @@ private boolean wrapResultSetsEnabled; private boolean orderUpdatesEnabled; private EntityMode defaultEntityMode; + private boolean dataDefinitionImplicitCommit; + private boolean dataDefinitionInTransactionSupported; + public boolean strictJPAQLCompliance; // private BytecodeProvider bytecodeProvider; - Settings() {} + /** + * Package protected constructor + */ + Settings() { + } + // public getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + public String getDefaultSchemaName() { return defaultSchemaName; } - public String getDefaultCatalogName() { - return defaultCatalogName; - } + public String getDefaultCatalogName() { + return defaultCatalogName; + } public Dialect getDialect() { return dialect; @@ -115,13 +123,140 @@ return minimalPutsEnabled; } + public Integer getJdbcFetchSize() { + return jdbcFetchSize; + } + + public ConnectionProvider getConnectionProvider() { + return connectionProvider; + } + + public TransactionFactory getTransactionFactory() { + return transactionFactory; + } + + public String getSessionFactoryName() { + return sessionFactoryName; + } + + public boolean isAutoCreateSchema() { + return autoCreateSchema; + } + + public boolean isAutoDropSchema() { + return autoDropSchema; + } + + public boolean isAutoUpdateSchema() { + return autoUpdateSchema; + } + + public Integer getMaximumFetchDepth() { + return maximumFetchDepth; + } + + public CacheProvider getCacheProvider() { + return cacheProvider; + } + + public TransactionManagerLookup getTransactionManagerLookup() { + return transactionManagerLookup; + } + + public boolean isQueryCacheEnabled() { + return queryCacheEnabled; + } + + public boolean isCommentsEnabled() { + return commentsEnabled; + } + + public boolean isSecondLevelCacheEnabled() { + return secondLevelCacheEnabled; + } + + public String getCacheRegionPrefix() { + return cacheRegionPrefix; + } + + public QueryCacheFactory getQueryCacheFactory() { + return queryCacheFactory; + } + + public boolean isStatisticsEnabled() { + return statisticsEnabled; + } + + public boolean isJdbcBatchVersionedData() { + return jdbcBatchVersionedData; + } + + public boolean isFlushBeforeCompletionEnabled() { + return flushBeforeCompletionEnabled; + } + + public BatcherFactory getBatcherFactory() { + return batcherFactory; + } + + public boolean isAutoCloseSessionEnabled() { + return autoCloseSessionEnabled; + } + + public ConnectionReleaseMode getConnectionReleaseMode() { + return connectionReleaseMode; + } + + public QueryTranslatorFactory getQueryTranslatorFactory() { + return queryTranslatorFactory; + } + + public SQLExceptionConverter getSQLExceptionConverter() { + return sqlExceptionConverter; + } + + public boolean isWrapResultSetsEnabled() { + return wrapResultSetsEnabled; + } + + public boolean isOrderUpdatesEnabled() { + return orderUpdatesEnabled; + } + + public boolean isStructuredCacheEntriesEnabled() { + return structuredCacheEntriesEnabled; + } + + public EntityMode getDefaultEntityMode() { + return defaultEntityMode; + } + + public boolean isAutoValidateSchema() { + return autoValidateSchema; + } + + public boolean isDataDefinitionImplicitCommit() { + return dataDefinitionImplicitCommit; + } + + public boolean isDataDefinitionInTransactionSupported() { + return dataDefinitionInTransactionSupported; + } + + public boolean isStrictJPAQLCompliance() { + return strictJPAQLCompliance; + } + + + // package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + void setDefaultSchemaName(String string) { defaultSchemaName = string; } - void setDefaultCatalogName(String string) { - defaultCatalogName = string; - } + void setDefaultCatalogName(String string) { + defaultCatalogName = string; + } void setDialect(Dialect dialect) { this.dialect = dialect; @@ -163,44 +298,22 @@ getGeneratedKeysEnabled = b; } - public Integer getJdbcFetchSize() { - return jdbcFetchSize; - } void setJdbcFetchSize(Integer integer) { jdbcFetchSize = integer; } - public ConnectionProvider getConnectionProvider() { - return connectionProvider; - } void setConnectionProvider(ConnectionProvider provider) { connectionProvider = provider; } - public TransactionFactory getTransactionFactory() { - return transactionFactory; - } void setTransactionFactory(TransactionFactory factory) { transactionFactory = factory; } - public String getSessionFactoryName() { - return sessionFactoryName; - } void setSessionFactoryName(String string) { sessionFactoryName = string; } - public boolean isAutoCreateSchema() { - return autoCreateSchema; - } - public boolean isAutoDropSchema() { - return autoDropSchema; - } - - public boolean isAutoUpdateSchema() { - return autoUpdateSchema; - } void setAutoCreateSchema(boolean b) { autoCreateSchema = b; } @@ -208,168 +321,114 @@ void setAutoDropSchema(boolean b) { autoDropSchema = b; } + void setAutoUpdateSchema(boolean b) { autoUpdateSchema = b; } - public Integer getMaximumFetchDepth() { - return maximumFetchDepth; - } void setMaximumFetchDepth(Integer i) { maximumFetchDepth = i; } - public CacheProvider getCacheProvider() { - return cacheProvider; - } void setCacheProvider(CacheProvider cacheProvider) { this.cacheProvider = cacheProvider; } - public TransactionManagerLookup getTransactionManagerLookup() { - return transactionManagerLookup; - } void setTransactionManagerLookup(TransactionManagerLookup lookup) { transactionManagerLookup = lookup; } - public boolean isQueryCacheEnabled() { - return queryCacheEnabled; - } void setQueryCacheEnabled(boolean b) { queryCacheEnabled = b; } - public boolean isCommentsEnabled() { - return commentsEnabled; - } void setCommentsEnabled(boolean commentsEnabled) { this.commentsEnabled = commentsEnabled; } - public boolean isSecondLevelCacheEnabled() { - return secondLevelCacheEnabled; - } void setSecondLevelCacheEnabled(boolean secondLevelCacheEnabled) { this.secondLevelCacheEnabled = secondLevelCacheEnabled; } - public String getCacheRegionPrefix() { - return cacheRegionPrefix; - } void setCacheRegionPrefix(String cacheRegionPrefix) { this.cacheRegionPrefix = cacheRegionPrefix; } - public QueryCacheFactory getQueryCacheFactory() { - return queryCacheFactory; - } - public void setQueryCacheFactory(QueryCacheFactory queryCacheFactory) { + void setQueryCacheFactory(QueryCacheFactory queryCacheFactory) { this.queryCacheFactory = queryCacheFactory; } - public boolean isStatisticsEnabled() { - return statisticsEnabled; - } void setStatisticsEnabled(boolean statisticsEnabled) { this.statisticsEnabled = statisticsEnabled; } - public boolean isJdbcBatchVersionedData() { - return jdbcBatchVersionedData; - } void setJdbcBatchVersionedData(boolean jdbcBatchVersionedData) { this.jdbcBatchVersionedData = jdbcBatchVersionedData; } - public boolean isFlushBeforeCompletionEnabled() { - return flushBeforeCompletionEnabled; - } void setFlushBeforeCompletionEnabled(boolean flushBeforeCompletionEnabled) { this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled; } - public BatcherFactory getBatcherFactory() { - return batcherFactory; - } void setBatcherFactory(BatcherFactory batcher) { this.batcherFactory = batcher; } - public boolean isAutoCloseSessionEnabled() { - return autoCloseSessionEnabled; - } void setAutoCloseSessionEnabled(boolean autoCloseSessionEnabled) { this.autoCloseSessionEnabled = autoCloseSessionEnabled; } - public ConnectionReleaseMode getConnectionReleaseMode() { - return connectionReleaseMode; - } - - public void setConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) { + void setConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) { this.connectionReleaseMode = connectionReleaseMode; } - public QueryTranslatorFactory getQueryTranslatorFactory() { - return queryTranslatorFactory; - } - void setQueryTranslatorFactory(QueryTranslatorFactory queryTranslatorFactory) { this.queryTranslatorFactory = queryTranslatorFactory; } - public SQLExceptionConverter getSQLExceptionConverter() { - return sqlExceptionConverter; - } - void setSQLExceptionConverter(SQLExceptionConverter sqlExceptionConverter) { this.sqlExceptionConverter = sqlExceptionConverter; } - public boolean isWrapResultSetsEnabled() { - return wrapResultSetsEnabled; - } - void setWrapResultSetsEnabled(boolean wrapResultSetsEnabled) { this.wrapResultSetsEnabled = wrapResultSetsEnabled; } - public boolean isOrderUpdatesEnabled() { - return orderUpdatesEnabled; - } void setOrderUpdatesEnabled(boolean orderUpdatesEnabled) { this.orderUpdatesEnabled = orderUpdatesEnabled; } - public boolean isStructuredCacheEntriesEnabled() { - return structuredCacheEntriesEnabled; - } void setStructuredCacheEntriesEnabled(boolean structuredCacheEntriesEnabled) { this.structuredCacheEntriesEnabled = structuredCacheEntriesEnabled; } - public EntityMode getDefaultEntityMode() { - return defaultEntityMode; + void setDefaultEntityMode(EntityMode defaultEntityMode) { + this.defaultEntityMode = defaultEntityMode; } - public void setDefaultEntityMode(EntityMode defaultEntityMode) { - this.defaultEntityMode = defaultEntityMode; + void setAutoValidateSchema(boolean autoValidateSchema) { + this.autoValidateSchema = autoValidateSchema; } - public boolean isAutoValidateSchema() { - return autoValidateSchema; + void setDataDefinitionImplicitCommit(boolean dataDefinitionImplicitCommit) { + this.dataDefinitionImplicitCommit = dataDefinitionImplicitCommit; } - void setAutoValidateSchema(boolean autoValidateSchema) { - this.autoValidateSchema = autoValidateSchema; + void setDataDefinitionInTransactionSupported(boolean dataDefinitionInTransactionSupported) { + this.dataDefinitionInTransactionSupported = dataDefinitionInTransactionSupported; } + void setStrictJPAQLCompliance(boolean strictJPAQLCompliance) { + this.strictJPAQLCompliance = strictJPAQLCompliance; + } + + + // public BytecodeProvider getBytecodeProvider() { // return bytecodeProvider; // } // -// public void setBytecodeProvider(BytecodeProvider bytecodeProvider) { +// void setBytecodeProvider(BytecodeProvider bytecodeProvider) { // this.bytecodeProvider = bytecodeProvider; // } } Modified: trunk/Hibernate3/src/org/hibernate/cfg/SettingsFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/SettingsFactory.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/cfg/SettingsFactory.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -63,12 +63,14 @@ settings.setConnectionProvider(connections); //Interrogate JDBC metadata - + + String databaseName = null; + int databaseMajorVersion = 0; boolean metaSupportsScrollable = false; boolean metaSupportsGetGeneratedKeys = false; boolean metaSupportsBatchUpdates = false; - String databaseName = null; - int databaseMajorVersion = 0; + boolean metaReportsDDLCausesTxnCommit = false; + boolean metaReportsDDLInTxnSupported = true; try { Connection conn = connections.getConnection(); @@ -81,6 +83,8 @@ metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE); metaSupportsBatchUpdates = meta.supportsBatchUpdates(); + metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit(); + metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions(); if ( Environment.jvmSupportsGetGeneratedKeys() ) { try { @@ -107,7 +111,10 @@ catch (UnsupportedOperationException uoe) { // user supplied JDBC connections } - + settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit ); + settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported ); + + //SQL Dialect: Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion ); settings.setDialect(dialect); @@ -204,6 +211,10 @@ Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties); log.info("Query language substitutions: " + querySubstitutions); settings.setQuerySubstitutions(querySubstitutions); + + boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false ); + settings.setStrictJPAQLCompliance( jpaqlCompliance ); + log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) ); // Second-level / query cache: Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -130,8 +130,13 @@ } } }; - if ( getFactory().getDialect().performTemporaryTableDDLInIsolation() ) { - Isolater.doIsolatedWork( work, session ); + if ( getFactory().getSettings().isDataDefinitionImplicitCommit() || getFactory().getDialect().performTemporaryTableDDLInIsolation() ) { + if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) { + Isolater.doIsolatedWork( work, session ); + } + else { + Isolater.doNonTransactedWork( work, session ); + } } else { work.doWork( session.getJDBCContext().getConnectionManager().getConnection() ); @@ -149,7 +154,7 @@ stmnt.executeUpdate( "drop table " + persister.getTemporaryIdTableName() ); } catch( Throwable t ) { - log.warn( "unable to drop temporary id table after use", t ); + log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" ); } finally { if ( stmnt != null ) { @@ -163,8 +168,13 @@ } } }; - if ( getFactory().getDialect().performTemporaryTableDDLInIsolation() ) { - Isolater.doIsolatedWork( work, session ); + if ( getFactory().getSettings().isDataDefinitionImplicitCommit() || getFactory().getDialect().performTemporaryTableDDLInIsolation() ) { + if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) { + Isolater.doIsolatedWork( work, session ); + } + else { + Isolater.doNonTransactedWork( work, session ); + } } else { work.doWork( session.getJDBCContext().getConnectionManager().getConnection() ); @@ -179,7 +189,7 @@ ps.executeUpdate(); } catch( Throwable t ) { - log.warn( "unable to cleanup temporary id table after use", t ); + log.warn( "unable to cleanup temporary id table after use [" + t + "]" ); } finally { if ( ps != null ) { Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SelectClause.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SelectClause.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/SelectClause.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -10,6 +10,7 @@ import org.hibernate.hql.ast.util.ASTAppender; import org.hibernate.hql.ast.util.ASTIterator; import org.hibernate.hql.ast.util.ASTPrinter; +import org.hibernate.hql.ast.QuerySyntaxException; import org.hibernate.type.Type; import org.hibernate.QueryException; @@ -255,6 +256,9 @@ if ( prepared ) { throw new IllegalStateException( "SelectClause was already prepared!" ); } + if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) { + throw new QuerySyntaxException( "JPA-QL compliance requires select clause" ); + } List fromElements = fromClause.getProjectionList(); ASTAppender appender = new ASTAppender( getASTFactory(), this ); // Get ready to start adding nodes. Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java 2006-06-06 17:20:50 UTC (rev 9988) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java 2006-06-06 17:21:38 UTC (rev 9989) @@ -379,4 +379,8 @@ public String[][] generateColumnNames(Type[] sqlResultTypes) { return NameGenerator.generateColumnNames( sqlResultTypes, sfi ); } + + public boolean isStrictJPAQLComplianceEnabled() { + return sfi.getSettings().isStrictJPAQLCompliance(); + } } |
From: <hib...@li...> - 2006-06-06 17:20:57
|
Author: ste...@jb... Date: 2006-06-06 13:20:50 -0400 (Tue, 06 Jun 2006) New Revision: 9988 Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/ql/ trunk/Hibernate3/test/org/hibernate/test/ejb3/ql/JPAQLCompatibilityTest.java Log: HHH-1817 : test cases Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/ql/JPAQLCompatibilityTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/ql/JPAQLCompatibilityTest.java 2006-06-06 03:50:59 UTC (rev 9987) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/ql/JPAQLCompatibilityTest.java 2006-06-06 17:20:50 UTC (rev 9988) @@ -0,0 +1,41 @@ +package org.hibernate.test.ejb3.ql; + +import org.hibernate.test.TestCase; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.Session; +import org.hibernate.QueryException; +import org.hibernate.hql.ast.QuerySyntaxException; + +/** + * todo: describe JPAQLCompatibilityTest + * + * @author Steve Ebersole + */ +public class JPAQLCompatibilityTest extends TestCase { + public JPAQLCompatibilityTest(String name) { + super( name ); + } + + protected String[] getMappings() { + return new String[] { "ejb3/Part.hbm.xml", "ejb3/Item.hbm.xml" }; + } + + protected void configure(Configuration cfg) { + super.configure( cfg ); + // todo : account for "compatibility flag" + cfg.setProperty( Environment.JPAQL_STRICT_COMPLIANCE, "true" ); + } + + public void testNoSelectClause() { + Session s = openSession(); + try { + s.createQuery( "from Part" ).list(); + fail( "expecting parse failure" ); + } + catch( QuerySyntaxException qe ) { + // expected behavior + } + s.close(); + } +} |
From: <hib...@li...> - 2006-06-06 03:51:20
|
Author: ste...@jb... Date: 2006-06-05 23:50:59 -0400 (Mon, 05 Jun 2006) New Revision: 9987 Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java Log: HHH-1816 : session deserialization - named session factory Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-06-05 21:42:05 UTC (rev 9986) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-06-06 03:50:59 UTC (rev 9987) @@ -1028,9 +1028,6 @@ * @throws IOException */ void serialize(ObjectOutputStream oos) throws IOException { - // we are only really concerned with the capability to deserialize - // this reference within the same JVM, so simply writing out the - // uuid is enough oos.writeUTF( uuid ); oos.writeBoolean( name != null ); if ( name != null ) { @@ -1047,14 +1044,19 @@ static SessionFactoryImpl deserialize(ObjectInputStream ois) throws IOException, ClassNotFoundException { String uuid = ois.readUTF(); boolean isNamed = ois.readBoolean(); + String name = null; if ( isNamed ) { - // todo : potentially use name for lookups on deserialization; - // needed for clustered failover of a session (i.e. stateful session bean) - String name = ois.readUTF(); + name = ois.readUTF(); } Object result = SessionFactoryObjectFactory.getInstance( uuid ); if ( result == null ) { - throw new InvalidObjectException( "could not locate session factory by uuid [" + uuid + "] during session deserialization" ); + log.trace( "could not locate session factory by uuid [" + uuid + "] during session deserialization; trying name" ); + if ( isNamed ) { + result = SessionFactoryObjectFactory.getNamedInstance( name ); + } + if ( result == null ) { + throw new InvalidObjectException( "could not resolve session factory during session deserialization [uuid=" + uuid + ", name=" + name + "]" ); + } } return ( SessionFactoryImpl ) result; } |