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
|
From: <one...@us...> - 2003-03-04 10:53:51
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test In directory sc8-pr-cvs1:/tmp/cvs-serv2690/sf/hibernate/test Modified Files: CustomPersister.java FooBarTest.java Log Message: made Query methods return this to allow chaining added experimental find(Class, Map) improved parsing of query imports, etc fixed a bug in PS handling Index: CustomPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test/CustomPersister.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** CustomPersister.java 28 Jan 2003 10:22:21 -0000 1.6 --- CustomPersister.java 4 Mar 2003 10:53:47 -0000 1.7 *************** *** 410,414 **** * @see net.sf.hibernate.persister.ClassPersister#getPropertySpaces(Object) */ ! public Serializable[] getPropertySpaces(Object instance) { return new String[] { "CUSTOMS" }; } --- 410,414 ---- * @see net.sf.hibernate.persister.ClassPersister#getPropertySpaces(Object) */ ! public Serializable[] getPropertySpaces() { return new String[] { "CUSTOMS" }; } Index: FooBarTest.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test/FooBarTest.java,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** FooBarTest.java 3 Mar 2003 09:31:07 -0000 1.36 --- FooBarTest.java 4 Mar 2003 10:53:47 -0000 1.37 *************** *** 12,15 **** --- 12,16 ---- import java.util.List; import java.util.Locale; + import java.util.Map; import java.util.Set; import java.util.TimeZone; *************** *** 133,136 **** --- 134,153 ---- s.connection().commit(); s.close(); + } + + public void testFindLike() throws Exception { + Session s = sessions.openSession(); + Foo f = new Foo(); + s.save(f); + s.flush(); + Map map = new HashMap(); + map.put( "integer", f.getInteger() ); + map.put( "string", f.getString() ); + map.put( "boolean", f.getBoolean() ); + List list = s.find(Foo.class, map); + assertTrue( list.size()==1 && list.get(0)==f ); + s.delete(f); + s.flush(); + s.close(); } |
From: <one...@us...> - 2003-03-04 10:53:51
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/loader In directory sc8-pr-cvs1:/tmp/cvs-serv2690/sf/hibernate/loader Modified Files: EntityLoader.java Loader.java Added Files: AbstractEntityLoader.java SearchLoader.java Log Message: made Query methods return this to allow chaining added experimental find(Class, Map) improved parsing of query imports, etc fixed a bug in PS handling --- NEW FILE: AbstractEntityLoader.java --- package net.sf.hibernate.loader; import java.util.List; import net.sf.hibernate.MappingException; import net.sf.hibernate.engine.SessionFactoryImplementor; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.sql.JoinFragment; import net.sf.hibernate.sql.Select; import net.sf.hibernate.util.StringHelper; public abstract class AbstractEntityLoader extends OuterJoinLoader { protected final Loadable persister; protected String alias; public AbstractEntityLoader(Loadable persister, SessionFactoryImplementor factory) { super( factory.getDialect() ); this.persister = persister; alias = alias( persister.getClassName(), 0 ); } protected void renderStatement(String condition, SessionFactoryImplementor factory) throws MappingException { List associations = walkTree(persister, alias, factory); int joins=associations.size(); suffixes = new String[joins+1]; for ( int i=0; i<=joins; i++ ) suffixes[i] = (joins==0) ? StringHelper.EMPTY_STRING : Integer.toString(i) + StringHelper.UNDERSCORE; JoinFragment ojf = outerJoins(associations); sql = new Select() .setSelectClause( ( joins==0 ? StringHelper.EMPTY_STRING : selectString(associations) + ", " ) + selectString( persister, alias, suffixes[joins] ) ) .setFromClause( persister.fromTableFragment(alias) + persister.fromJoinFragment(alias, true, true) ) .setWhereClause(condition) .setOuterJoins( ojf.toFromFragmentString(), ojf.toWhereFragmentString() + persister.whereJoinFragment(alias, true, true) ) .toStatementString(); classPersisters = new Loadable[joins+1]; for ( int i=0; i<joins; i++ ) classPersisters[i] = ( (OuterJoinableAssociation) associations.get(i) ).subpersister; classPersisters[joins] = persister; } } --- NEW FILE: SearchLoader.java --- package net.sf.hibernate.loader; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; import net.sf.hibernate.HibernateException; import net.sf.hibernate.MappingException; import net.sf.hibernate.engine.SessionFactoryImplementor; import net.sf.hibernate.engine.SessionImplementor; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.type.Type; public class SearchLoader extends AbstractEntityLoader { private String[] propertyNames; private int[] propertyIndexes; private Type[] propertyTypes; private SessionFactoryImplementor factory; public SearchLoader(Loadable persister, SessionFactoryImplementor factory, String[] propertyNames) throws MappingException { super(persister, factory); this.propertyNames=propertyNames; this.factory = factory; propertyIndexes = new int[propertyNames.length]; propertyTypes = new Type[propertyNames.length]; Type[] types = persister.getPropertyTypes(); String[] allPropertyNames = persister.getPropertyNames(); for ( int i=0; i<propertyNames.length; i++ ) { int prop=-1; for ( int k=0; k<allPropertyNames.length; k++ ) { if ( allPropertyNames[k].equals(propertyNames[i]) ) { prop=k; break; } } //TODO: not a MappingException if (prop==-1) throw new MappingException("property not found: " + propertyNames[i]); propertyIndexes[i] = prop; propertyTypes[i] = types[prop]; } renderStatement( getConditionString(), factory ); } protected String getConditionString() throws MappingException { StringBuffer buffer = new StringBuffer(); int count=0; for ( int i=0; i<propertyNames.length; i++ ) { //TODO: handle null values using IS NULL String[] columnNames = persister.getPropertyColumnNames(propertyIndexes[i]); int[] sqlTypes = propertyTypes[i].sqlTypes(factory); for ( int j=0; j<columnNames.length; j++ ) { if (0 < count++) buffer.append(" and "); String op = ( sqlTypes[j]==Types.VARCHAR ) ? " like ?" : "=?"; buffer.append(alias).append('.').append( columnNames[j] ).append(op); } } return buffer.toString(); } public List list(SessionImplementor session, Map propertyNameValues) throws HibernateException, SQLException { Object[] values = new Object[propertyNames.length]; for ( int i=0; i<propertyNames.length; i++ ) { values[i] = propertyNameValues.get( propertyNames[i] ); } return find(session, values, propertyTypes, true, null, null); } protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { return row[ row.length-1 ]; } } Index: EntityLoader.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/loader/EntityLoader.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** EntityLoader.java 23 Feb 2003 07:22:11 -0000 1.11 --- EntityLoader.java 4 Mar 2003 10:53:47 -0000 1.12 *************** *** 10,69 **** import net.sf.hibernate.engine.SessionFactoryImplementor; import net.sf.hibernate.engine.SessionImplementor; - import net.sf.hibernate.persister.ClassPersister; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.sql.ConditionFragment; - import net.sf.hibernate.sql.JoinFragment; - import net.sf.hibernate.sql.Select; import net.sf.hibernate.type.Type; - import net.sf.hibernate.util.StringHelper; /** * Load an entity using outerjoin fetching to fetch associated entities. */ ! public class EntityLoader extends OuterJoinLoader implements UniqueEntityLoader { private final Type[] idType; - private final ClassPersister persister; public EntityLoader(Loadable persister, SessionFactoryImplementor factory) throws MappingException { ! ! super( factory.getDialect() ); idType = new Type[] { persister.getIdentifierType() }; - this.persister = persister; - - String alias = alias( persister.getClassName(), 0 ); - - List associations = walkTree(persister, alias, factory); ! int joins=associations.size(); ! suffixes = new String[joins+1]; ! for ( int i=0; i<=joins; i++ ) suffixes[i] = (joins==0) ? StringHelper.EMPTY_STRING : Integer.toString(i) + StringHelper.UNDERSCORE; ! ! JoinFragment ojf = outerJoins(associations); ! sql = new Select() ! .setSelectClause( ! ( joins==0 ? StringHelper.EMPTY_STRING : selectString(associations) + ", " ) + ! selectString( persister, alias, suffixes[joins] ) ! ) ! .setFromClause( ! persister.fromTableFragment(alias) + ! persister.fromJoinFragment(alias, true, true) ! ) ! .setWhereClause( ! new ConditionFragment().setTableAlias(alias) ! .setCondition( persister.getIdentifierColumnNames(), "?" ) ! .toFragmentString() ! ) ! .setOuterJoins( ! ojf.toFromFragmentString(), ! ojf.toWhereFragmentString() + ! persister.whereJoinFragment(alias, true, true) ! ) ! .toStatementString(); ! classPersisters = new Loadable[joins+1]; ! for ( int i=0; i<joins; i++ ) classPersisters[i] = ( (OuterJoinableAssociation) associations.get(i) ).subpersister; ! classPersisters[joins] = persister; } --- 10,34 ---- import net.sf.hibernate.engine.SessionFactoryImplementor; import net.sf.hibernate.engine.SessionImplementor; import net.sf.hibernate.persister.Loadable; import net.sf.hibernate.sql.ConditionFragment; import net.sf.hibernate.type.Type; /** * Load an entity using outerjoin fetching to fetch associated entities. */ ! public class EntityLoader extends AbstractEntityLoader implements UniqueEntityLoader { private final Type[] idType; public EntityLoader(Loadable persister, SessionFactoryImplementor factory) throws MappingException { ! super(persister, factory); idType = new Type[] { persister.getIdentifierType() }; ! String condition = new ConditionFragment().setTableAlias(alias) ! .setCondition( persister.getIdentifierColumnNames(), "?" ) ! .toFragmentString(); ! renderStatement(condition, factory); } *************** *** 78,84 **** } else { ! throw new HibernateException( "More than one row with the given identifier was found: " + id + ", for class: " + persister.getClassName() ); } } } --- 43,55 ---- } else { ! throw new HibernateException( ! "More than one row with the given identifier was found: " + ! id + ! ", for class: " + ! persister.getClassName() ! ); } } + } Index: Loader.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/loader/Loader.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Loader.java 23 Feb 2003 01:32:20 -0000 1.12 --- Loader.java 4 Mar 2003 10:53:47 -0000 1.13 *************** *** 169,173 **** } finally { ! session.getBatcher().closeQueryStatement(st); } } --- 169,173 ---- } finally { ! closePreparedStatement(st, selection, session); } } *************** *** 390,398 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } catch (HibernateException he) { ! session.getBatcher().closeQueryStatement(st); throw he; } --- 390,398 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } catch (HibernateException he) { ! closePreparedStatement(st, selection, session); throw he; } *************** *** 424,432 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); throw sqle; } catch (HibernateException he) { ! session.getBatcher().closeQueryStatement(st); throw he; } } --- 424,445 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); + closePreparedStatement(st, selection, session); throw sqle; } catch (HibernateException he) { ! closePreparedStatement(st, selection, session); throw he; + } + } + + protected final void closePreparedStatement(PreparedStatement st, RowSelection selection, SessionImplementor session) throws SQLException, HibernateException { + try { + if (selection!=null) { + if (selection.getMaxRows()!=null) st.setMaxRows(0); + if (selection.getTimeout()!=null) st.setQueryTimeout(0); + } + } + finally { + session.getBatcher().closeQueryStatement(st); } } |
From: <one...@us...> - 2003-03-04 10:53:49
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate In directory sc8-pr-cvs1:/tmp/cvs-serv2690/sf/hibernate Modified Files: Query.java Session.java Log Message: made Query methods return this to allow chaining added experimental find(Class, Map) improved parsing of query imports, etc fixed a bug in PS handling Index: Query.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/Query.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Query.java 31 Jan 2003 08:49:49 -0000 1.7 --- Query.java 4 Mar 2003 10:53:46 -0000 1.8 *************** *** 111,115 **** * @param maxResults the maximum number of rows */ ! public void setMaxResults(int maxResults); /** * Set the first row to retrieve. If not set, rows will be --- 111,115 ---- * @param maxResults the maximum number of rows */ ! public Query setMaxResults(int maxResults); /** * Set the first row to retrieve. If not set, rows will be *************** *** 119,123 **** * @param firstResult a row number, numbered from <tt>0</tt> */ ! public void setFirstResult(int firstResult); /** --- 119,123 ---- * @param firstResult a row number, numbered from <tt>0</tt> */ ! public Query setFirstResult(int firstResult); /** *************** *** 125,129 **** * @param timeout the timeout in seconds */ ! public void setTimeout(int timeout); /** --- 125,129 ---- * @param timeout the timeout in seconds */ ! public Query setTimeout(int timeout); /** *************** *** 134,138 **** * @param type the Hibernate type */ ! public void setParameter(int position, Object val, Type type); /** * Bind a value to a named query parameter. --- 134,138 ---- * @param type the Hibernate type */ ! public Query setParameter(int position, Object val, Type type); /** * Bind a value to a named query parameter. *************** *** 141,145 **** * @param type the Hibernate type */ ! public void setParameter(String name, Object val, Type type); /** --- 141,145 ---- * @param type the Hibernate type */ ! public Query setParameter(String name, Object val, Type type); /** *************** *** 151,155 **** * @throws net.sf.hibernate.HibernateException if no type could be determined */ ! public void setParameter(int position, Object val) throws HibernateException; /** * Bind a value to a named query parameter, guessing the Hibernate --- 151,155 ---- * @throws net.sf.hibernate.HibernateException if no type could be determined */ ! public Query setParameter(int position, Object val) throws HibernateException; /** * Bind a value to a named query parameter, guessing the Hibernate *************** *** 159,163 **** * @throws net.sf.hibernate.HibernateException if no type could be determined */ ! public void setParameter(String name, Object val) throws HibernateException; /** --- 159,163 ---- * @throws net.sf.hibernate.HibernateException if no type could be determined */ ! public Query setParameter(String name, Object val) throws HibernateException; /** *************** *** 168,172 **** * @param type the Hibernate type of the values */ ! public void setParameterList(String name, Collection vals, Type type) throws HibernateException; /** --- 168,172 ---- * @param type the Hibernate type of the values */ ! public Query setParameterList(String name, Collection vals, Type type) throws HibernateException; /** *************** *** 177,181 **** * @param vals a collection of values to list */ ! public void setParameterList(String name, Collection vals) throws HibernateException; /** --- 177,181 ---- * @param vals a collection of values to list */ ! public Query setParameterList(String name, Collection vals) throws HibernateException; /** *************** *** 185,231 **** * @param bean any JavaBean or POJO */ ! public void setProperties(Object bean) throws HibernateException; ! public void setString(int position, String val); ! public void setCharacter(int position, char val); ! public void setBoolean(int position, boolean val); ! public void setByte(int position, byte val); ! public void setShort(int position, short val); ! public void setInteger(int position, int val); ! public void setLong(int position, long val); ! public void setFloat(int position, float val); ! public void setDouble(int position, double val); ! public void setBinary(int position, byte[] val); ! public void setSerializable(int position, Serializable val); ! public void setLocale(int position, Locale locale); ! public void setBigDecimal(int position, BigDecimal number); ! public void setDate(int position, Date date); ! public void setTime(int position, Date date); ! public void setTimestamp(int position, Date date); ! public void setCalendar(int position, Calendar calendar); ! public void setCalendarDate(int position, Calendar calendar); ! public void setString(String name, String val); ! public void setCharacter(String name, char val); ! public void setBoolean(String name, boolean val); ! public void setByte(String name, byte val); ! public void setShort(String name, short val); ! public void setInteger(String name, int val); ! public void setLong(String name, long val); ! public void setFloat(String name, float val); ! public void setDouble(String name, double val); ! public void setBinary(String name, byte[] val); ! public void setSerializable(String name, Serializable val); ! public void setLocale(String name, Locale locale); ! public void setBigDecimal(String name, BigDecimal number); ! public void setDate(String name, Date date); ! public void setTime(String name, Date date); ! public void setTimestamp(String name, Date date); ! public void setCalendar(String name, Calendar calendar); ! public void setCalendarDate(String name, Calendar calendar); /** --- 185,231 ---- * @param bean any JavaBean or POJO */ ! public Query setProperties(Object bean) throws HibernateException; ! public Query setString(int position, String val); ! public Query setCharacter(int position, char val); ! public Query setBoolean(int position, boolean val); ! public Query setByte(int position, byte val); ! public Query setShort(int position, short val); ! public Query setInteger(int position, int val); ! public Query setLong(int position, long val); ! public Query setFloat(int position, float val); ! public Query setDouble(int position, double val); ! public Query setBinary(int position, byte[] val); ! public Query setSerializable(int position, Serializable val); ! public Query setLocale(int position, Locale locale); ! public Query setBigDecimal(int position, BigDecimal number); ! public Query setDate(int position, Date date); ! public Query setTime(int position, Date date); ! public Query setTimestamp(int position, Date date); ! public Query setCalendar(int position, Calendar calendar); ! public Query setCalendarDate(int position, Calendar calendar); ! public Query setString(String name, String val); ! public Query setCharacter(String name, char val); ! public Query setBoolean(String name, boolean val); ! public Query setByte(String name, byte val); ! public Query setShort(String name, short val); ! public Query setInteger(String name, int val); ! public Query setLong(String name, long val); ! public Query setFloat(String name, float val); ! public Query setDouble(String name, double val); ! public Query setBinary(String name, byte[] val); ! public Query setSerializable(String name, Serializable val); ! public Query setLocale(String name, Locale locale); ! public Query setBigDecimal(String name, BigDecimal number); ! public Query setDate(String name, Date date); ! public Query setTime(String name, Date date); ! public Query setTimestamp(String name, Date date); ! public Query setCalendar(String name, Calendar calendar); ! public Query setCalendarDate(String name, Calendar calendar); /** *************** *** 235,239 **** * @param val a non-null instance of a persistent class */ ! public void setEntity(int position, Object val); // use setParameter for null values /** * Bind an instance of a persistent enumeration class to a JDBC-style query parameter. --- 235,239 ---- * @param val a non-null instance of a persistent class */ ! public Query setEntity(int position, Object val); // use setParameter for null values /** * Bind an instance of a persistent enumeration class to a JDBC-style query parameter. *************** *** 242,246 **** * @param val a non-null instance of a persistent enumeration */ ! public void setEnum(int position, Object val) throws MappingException; // use setParameter for null values /** --- 242,246 ---- * @param val a non-null instance of a persistent enumeration */ ! public Query setEnum(int position, Object val) throws MappingException; // use setParameter for null values /** *************** *** 249,253 **** * @param val a non-null instance of a persistent class */ ! public void setEntity(String name, Object val); // use setParameter for null values /** * Bind an instance of a mapped persistent enumeration class to a named query parameter. --- 249,253 ---- * @param val a non-null instance of a persistent class */ ! public Query setEntity(String name, Object val); // use setParameter for null values /** * Bind an instance of a mapped persistent enumeration class to a named query parameter. *************** *** 255,259 **** * @param val a non-null instance of a persistent enumeration */ ! public void setEnum(String name, Object val) throws MappingException; // use setParameter for null values } --- 255,259 ---- * @param val a non-null instance of a persistent enumeration */ ! public Query setEnum(String name, Object val) throws MappingException; // use setParameter for null values } Index: Session.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/Session.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Session.java 24 Feb 2003 11:53:45 -0000 1.7 --- Session.java 4 Mar 2003 10:53:46 -0000 1.8 *************** *** 8,11 **** --- 8,12 ---- import java.util.Iterator; import java.util.List; + import java.util.Map; /** * The main runtime interface between a Java application and Hibernate. This is the *************** *** 277,280 **** --- 278,291 ---- public List find(String query) throws HibernateException; + /** + * Find persistent instances with the given property values + * + * @param persistentClass a persistent class + * @param propertyNameValues property name / value pairs + * @return List + * @throws HibernateException + */ + public List find(Class persistentClass, Map propertyNameValues) throws HibernateException; + /** * Execute a query, binding a value to a "?" parameter in the query string. |
From: <one...@us...> - 2003-03-04 10:53:49
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv2690/sf/hibernate/hql Modified Files: QueryTranslator.java Log Message: made Query methods return this to allow chaining added experimental find(Class, Map) improved parsing of query imports, etc fixed a bug in PS handling Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** QueryTranslator.java 3 Mar 2003 09:31:03 -0000 1.18 --- QueryTranslator.java 4 Mar 2003 10:53:46 -0000 1.19 *************** *** 735,739 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } --- 735,739 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } *************** *** 752,756 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } --- 752,756 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } |
From: <one...@us...> - 2003-03-04 10:43:10
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/loader In directory sc8-pr-cvs1:/tmp/cvs-serv31778/hibernate/loader Modified Files: Loader.java Log Message: fixed problem with cached prepared statement handling Index: Loader.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/loader/Loader.java,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** Loader.java 15 Jan 2003 12:52:40 -0000 1.34 --- Loader.java 4 Mar 2003 10:43:06 -0000 1.35 *************** *** 211,215 **** } finally { ! session.getBatcher().closeQueryStatement(st); } } --- 211,215 ---- } finally { ! closePreparedStatement(st, selection, session); } } *************** *** 430,438 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } catch (HibernateException he) { ! session.getBatcher().closeQueryStatement(st); throw he; } --- 430,438 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } catch (HibernateException he) { ! closePreparedStatement(st, selection, session); throw he; } *************** *** 441,444 **** --- 441,456 ---- } + protected final void closePreparedStatement(PreparedStatement st, QueryImpl.RowSelection selection, SessionImplementor session) throws SQLException, HibernateException { + try { + if (selection!=null) { + if (selection.maxRows!=null) st.setMaxRows(0); + if (selection.timeout!=null) st.setQueryTimeout(0); + } + } + finally { + session.getBatcher().closeQueryStatement(st); + } + } + /** * Limit the number of rows returned by the SQL query if necessary *************** *** 464,471 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); throw sqle; } catch (HibernateException he) { ! session.getBatcher().closeQueryStatement(st); throw he; } --- 476,484 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); + closePreparedStatement(st, selection, session); throw sqle; } catch (HibernateException he) { ! closePreparedStatement(st, selection, session); throw he; } |
From: <one...@us...> - 2003-03-04 10:43:09
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/query In directory sc8-pr-cvs1:/tmp/cvs-serv31778/hibernate/query Modified Files: QueryTranslator.java Log Message: fixed problem with cached prepared statement handling Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/QueryTranslator.java,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** QueryTranslator.java 28 Dec 2002 02:25:49 -0000 1.52 --- QueryTranslator.java 4 Mar 2003 10:43:06 -0000 1.53 *************** *** 808,812 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } --- 808,812 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } *************** *** 825,829 **** catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! session.getBatcher().closeQueryStatement(st); throw sqle; } --- 825,829 ---- catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); ! closePreparedStatement(st, selection, session); throw sqle; } *************** *** 867,871 **** } finally { ! session.getBatcher().closeQueryStatement(st); } return list; --- 867,871 ---- } finally { ! closePreparedStatement(st, null, session); } return list; |
From: <one...@us...> - 2003-03-04 10:43:09
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/impl In directory sc8-pr-cvs1:/tmp/cvs-serv31778/hibernate/impl Modified Files: SessionFactoryImpl.java Log Message: fixed problem with cached prepared statement handling Index: SessionFactoryImpl.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/impl/SessionFactoryImpl.java,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** SessionFactoryImpl.java 19 Feb 2003 12:43:24 -0000 1.63 --- SessionFactoryImpl.java 4 Mar 2003 10:43:06 -0000 1.64 *************** *** 261,268 **** //Queries: ! querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:", properties); log.info("Query language substitutions: " + querySubstitutions); ! queryImports = PropertiesHelper.toStringArray(Environment.QUERY_IMPORTS, " ,;:", properties); if ( queryImports.length!=0 ) log.info( "Query language imports: " + StringHelper.toString(queryImports) ); --- 261,268 ---- //Queries: ! querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties); log.info("Query language substitutions: " + querySubstitutions); ! queryImports = PropertiesHelper.toStringArray(Environment.QUERY_IMPORTS, " ,;:\n\t\r\f", properties); if ( queryImports.length!=0 ) log.info( "Query language imports: " + StringHelper.toString(queryImports) ); *************** *** 494,499 **** public void closePreparedStatement(PreparedStatement ps) throws SQLException { if (stCache!=null) { - ps.setMaxRows(0); - ps.setFetchSize(0); stCache.closePreparedStatement(ps); } --- 494,497 ---- |
From: <one...@us...> - 2003-03-03 09:31:51
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test In directory sc8-pr-cvs1:/tmp/cvs-serv21958/sf/hibernate/test Modified Files: FooBarTest.java MultiTableTest.java Log Message: fixed minor problems with new HQL stuff: * return ALL joined objects mentioned in FROM clause (iff no select clause) * throw a meaningful exception when property is not found made name attribute optional in hibernate.cfg.xml Index: FooBarTest.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test/FooBarTest.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** FooBarTest.java 2 Mar 2003 12:58:52 -0000 1.35 --- FooBarTest.java 3 Mar 2003 09:31:07 -0000 1.36 *************** *** 69,74 **** s.save(baz); s.save(bar2); Query q = s.createQuery("select bar, b from Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like 'Bar%'"); ! List list = q.list(); assertTrue( list.size()==2 ); --- 69,79 ---- s.save(baz); s.save(bar2); + + List list = s.find("from Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like 'Bar%'"); + Object row = list.iterator().next(); + assertTrue( row instanceof Object[] && ( (Object[]) row ).length==3 ); + Query q = s.createQuery("select bar, b from Bar bar left join bar.baz baz left join baz.cascadingBars b where bar.name like 'Bar%'"); ! list = q.list(); assertTrue( list.size()==2 ); Index: MultiTableTest.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/test/MultiTableTest.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** MultiTableTest.java 23 Feb 2003 01:32:21 -0000 1.7 --- MultiTableTest.java 3 Mar 2003 09:31:13 -0000 1.8 *************** *** 22,25 **** --- 22,36 ---- } + public void testJoins() throws Exception { + Session s = sessions.openSession(); + s.find("select s, ya from LessSimple s join s.yetanother ya"); + s.find("from LessSimple s1 join s1.bag s2"); + s.find("from LessSimple s1 left join s1.bag s2"); + s.find("select s, a from LessSimple s join s.another a"); + s.find("select s, a from LessSimple s left join s.another a"); + s.find("from Simple s, LessSimple ls"); + s.close(); + } + public void testQueries() throws Exception { |
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql In directory sc8-pr-cvs1:/tmp/cvs-serv21958/sf/hibernate/hql Modified Files: FromParser.java GroupByParser.java OrderByParser.java PathExpressionParser.java QueryTranslator.java SelectParser.java WhereParser.java Log Message: fixed minor problems with new HQL stuff: * return ALL joined objects mentioned in FROM clause (iff no select clause) * throw a meaningful exception when property is not found made name attribute optional in hibernate.cfg.xml Index: FromParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/FromParser.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** FromParser.java 2 Mar 2003 12:58:52 -0000 1.10 --- FromParser.java 3 Mar 2003 09:30:57 -0000 1.11 *************** *** 103,107 **** if (classPersister!=null) { ! q.addCrossJoinedFromType(token, classPersister); } else if (entityName!=null) { --- 103,107 ---- if (classPersister!=null) { ! q.addFromClass(token, classPersister); } else if (entityName!=null) { *************** *** 131,135 **** Loadable p = q.getPersisterUsingImports(token); if (p==null) throw new QueryException("persister not found: " + token); ! q.addCrossJoinedFromType(alias, p); } else { --- 131,135 ---- Loadable p = q.getPersisterUsingImports(token); if (p==null) throw new QueryException("persister not found: " + token); ! q.addFromClass(alias, p); } else { Index: GroupByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/GroupByParser.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GroupByParser.java 28 Feb 2003 07:01:28 -0000 1.5 --- GroupByParser.java 3 Mar 2003 09:30:58 -0000 1.6 *************** *** 27,31 **** ParserHelper.parse(pathExpressionParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); q.appendGroupByToken( pathExpressionParser.getWhereColumn() ); ! pathExpressionParser.addFromAssociation(q); } else { --- 27,31 ---- ParserHelper.parse(pathExpressionParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); q.appendGroupByToken( pathExpressionParser.getWhereColumn() ); ! pathExpressionParser.addAssociation(q); } else { Index: OrderByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/OrderByParser.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** OrderByParser.java 28 Feb 2003 07:01:28 -0000 1.5 --- OrderByParser.java 3 Mar 2003 09:31:00 -0000 1.6 *************** *** 26,30 **** ParserHelper.parse(pathExpressionParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); q.appendOrderByToken( pathExpressionParser.getWhereColumn() ); ! pathExpressionParser.addFromAssociation(q); } else { --- 26,30 ---- ParserHelper.parse(pathExpressionParser, q.unalias(token), ParserHelper.PATH_SEPARATORS, q); q.appendOrderByToken( pathExpressionParser.getWhereColumn() ); ! pathExpressionParser.addAssociation(q); } else { Index: PathExpressionParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/PathExpressionParser.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PathExpressionParser.java 2 Mar 2003 06:58:48 -0000 1.12 --- PathExpressionParser.java 3 Mar 2003 09:31:02 -0000 1.13 *************** *** 200,208 **** protected Type getPropertyType(QueryTranslator q) throws QueryException { ! return q.getPersisterForName(currentName).getPropertyType( getPropertyPath() ); } protected String[] currentColumns(QueryTranslator q) throws QueryException { ! return q.getPersisterForName(currentName).toColumns( currentName, getPropertyPath() ); } --- 200,214 ---- protected Type getPropertyType(QueryTranslator q) throws QueryException { ! String path = getPropertyPath(); ! Type type = q.getPersisterForName(currentName).getPropertyType(path); ! if (type==null) throw new QueryException("could not resolve property type: " + path); ! return type; } protected String[] currentColumns(QueryTranslator q) throws QueryException { ! String path = getPropertyPath(); ! String[] columns = q.getPersisterForName(currentName).toColumns(currentName, path); ! if (columns==null) throw new QueryException("could not resolve property columns: " + path); ! return columns; } *************** *** 356,361 **** } ! public String addFromAssociation(QueryTranslator q) { q.addJoin( getName(), join ); return currentName; } --- 362,371 ---- } ! public void addAssociation(QueryTranslator q) { q.addJoin( getName(), join ); + } + + public String addFromAssociation(QueryTranslator q) { + q.addFrom(currentName, join); return currentName; } *************** *** 385,389 **** join.addJoin( p.getTableName(), elementName, collectionElementColumns, keyColumnNames, joinType); } ! q.addFromType(elementName, clazz, join, false); return elementName; --- 395,399 ---- join.addJoin( p.getTableName(), elementName, collectionElementColumns, keyColumnNames, joinType); } ! q.addFrom(elementName, clazz, join); return elementName; Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/QueryTranslator.java,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** QueryTranslator.java 2 Mar 2003 06:58:48 -0000 1.17 --- QueryTranslator.java 3 Mar 2003 09:31:03 -0000 1.18 *************** *** 17,21 **** import java.util.StringTokenizer; - import net.sf.hibernate.AssertionFailure; import net.sf.hibernate.Hibernate; import net.sf.hibernate.HibernateException; --- 17,20 ---- *************** *** 204,223 **** } - /** - * Return the SQL for a <tt>find()</tt> style query. - * @return the SQL as a string - */ protected String getSQLString() { - if ( shallowQuery ) throw new AssertionFailure(""); - logQuery(queryString, sqlString); - return sqlString; - } - - /** - * Return the SQL for an <tt>iterate()</tt> style query. - * @return the SQL as a string - */ - protected String getScalarSelectSQL() { - if ( !shallowQuery ) throw new AssertionFailure(""); logQuery(queryString, sqlString); return sqlString; --- 203,207 ---- *************** *** 322,344 **** } ! void addFromType(String name, Class type, JoinFragment join, boolean crossJoin) { ! //TODO: join type!! addType(name, type); fromTypes.add(name); addJoin(name, join); - if (crossJoin) crossJoins.add(name); } ! void addCrossJoinedFromType(String name, Loadable classPersister) { JoinFragment ojf = createJoinFragment(); ojf.addCrossJoin( classPersister.getTableName(), name ); ! addFromType(name, classPersister.getMappedClass(), ojf, true); } ! void addReturnType(String name) { returnTypes.add(name); } ! void addScalarType(Type type) { scalarTypes.add(type); } --- 306,331 ---- } ! void addFrom(String name, Class type, JoinFragment join) { addType(name, type); + addFrom(name, join); + } + + void addFrom(String name, JoinFragment join) { fromTypes.add(name); addJoin(name, join); } ! void addFromClass(String name, Loadable classPersister) { JoinFragment ojf = createJoinFragment(); ojf.addCrossJoin( classPersister.getTableName(), name ); ! crossJoins.add(name); ! addFrom(name, classPersister.getMappedClass(), ojf); } ! void addSelectClass(String name) { returnTypes.add(name); } ! void addSelectScalar(Type type) { scalarTypes.add(type); } *************** *** 700,704 **** ); } ! addFromType(elementName, elemType.getPersistentClass(), join, false); } --- 687,691 ---- ); } ! addFrom(elementName, elemType.getPersistentClass(), join); } *************** *** 738,742 **** public Iterator iterate(Object[] values, Type[] types, RowSelection selection, Map namedParams, SessionImplementor session) throws HibernateException, SQLException { ! PreparedStatement st = prepareQueryStatement( getScalarSelectSQL(), values, types, selection, false, session ); try { bindNamedParameters(st, namedParams, session); --- 725,729 ---- public Iterator iterate(Object[] values, Type[] types, RowSelection selection, Map namedParams, SessionImplementor session) throws HibernateException, SQLException { ! PreparedStatement st = prepareQueryStatement( getSQLString(), values, types, selection, false, session ); try { bindNamedParameters(st, namedParams, session); *************** *** 755,759 **** public ScrollableResults scroll(Object[] values, Type[] types, RowSelection selection, Map namedParams, SessionImplementor session) throws HibernateException, SQLException { ! PreparedStatement st = prepareQueryStatement( getScalarSelectSQL(), values, types, selection, true, session ); try { bindNamedParameters(st, namedParams, session); --- 742,746 ---- public ScrollableResults scroll(Object[] values, Type[] types, RowSelection selection, Map namedParams, SessionImplementor session) throws HibernateException, SQLException { ! PreparedStatement st = prepareQueryStatement( getSQLString(), values, types, selection, true, session ); try { bindNamedParameters(st, namedParams, session); Index: SelectParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/SelectParser.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** SelectParser.java 1 Mar 2003 12:15:27 -0000 1.7 --- SelectParser.java 3 Mar 2003 09:31:05 -0000 1.8 *************** *** 104,108 **** if (!ready) throw new QueryException(", expected before aggregate function in SELECT: " + token); if ( lctoken.equals("count") ) { ! q.addScalarType(Hibernate.INTEGER); count = true; } --- 104,108 ---- if (!ready) throw new QueryException(", expected before aggregate function in SELECT: " + token); if ( lctoken.equals("count") ) { ! q.addSelectScalar(Hibernate.INTEGER); count = true; } *************** *** 122,127 **** } q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() ); ! if (!count) q.addScalarType( aggregatePathExpressionParser.getWhereColumnType() ); ! aggregatePathExpressionParser.addFromAssociation(q); } else { --- 122,127 ---- } q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() ); ! if (!count) q.addSelectScalar( aggregatePathExpressionParser.getWhereColumnType() ); ! aggregatePathExpressionParser.addAssociation(q); } else { *************** *** 136,144 **** } else if ( pathExpressionParser.getWhereColumnType().isEntityType() ) { ! q.addReturnType( pathExpressionParser.getSelectName() ); } q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() ); ! q.addScalarType( pathExpressionParser.getWhereColumnType() ); ! pathExpressionParser.addFromAssociation(q); ready = false; --- 136,144 ---- } else if ( pathExpressionParser.getWhereColumnType().isEntityType() ) { ! q.addSelectClass( pathExpressionParser.getSelectName() ); } q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() ); ! q.addSelectScalar( pathExpressionParser.getWhereColumnType() ); ! pathExpressionParser.addAssociation(q); ready = false; Index: WhereParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hql/WhereParser.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** WhereParser.java 2 Mar 2003 06:58:49 -0000 1.10 --- WhereParser.java 3 Mar 2003 09:31:06 -0000 1.11 *************** *** 237,241 **** throw new QueryException("MappingException occurred compiling subquery", me ); } ! appendToken( q, subq.getScalarSelectSQL() ); inSubselect = false; bracketsSinceSelect=0; --- 237,241 ---- throw new QueryException("MappingException occurred compiling subquery", me ); } ! appendToken( q, subq.getSQLString() ); inSubselect = false; bracketsSinceSelect=0; |
From: <one...@us...> - 2003-03-03 09:31:36
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate In directory sc8-pr-cvs1:/tmp/cvs-serv21958/sf/hibernate Modified Files: hibernate-configuration-2.0.dtd Log Message: fixed minor problems with new HQL stuff: * return ALL joined objects mentioned in FROM clause (iff no select clause) * throw a meaningful exception when property is not found made name attribute optional in hibernate.cfg.xml Index: hibernate-configuration-2.0.dtd =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/hibernate-configuration-2.0.dtd,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** hibernate-configuration-2.0.dtd 2 Feb 2003 00:29:06 -0000 1.3 --- hibernate-configuration-2.0.dtd 3 Mar 2003 09:30:56 -0000 1.4 *************** *** 14,18 **** <!ELEMENT property (#PCDATA)> ! <!ATTLIST property name CDATA #REQUIRED> <!ELEMENT mapping EMPTY> <!-- reference to a mapping file --> --- 14,18 ---- <!ELEMENT property (#PCDATA)> ! <!ATTLIST property name CDATA #IMPLIED> <!ELEMENT mapping EMPTY> <!-- reference to a mapping file --> |
From: <tu...@us...> - 2003-03-03 06:39:19
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/src In directory sc8-pr-cvs1:/tmp/cvs-serv1377/src Modified Files: manipulating_data.xml Log Message: We don't have toplevel collections anymore Index: manipulating_data.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/manipulating_data.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** manipulating_data.xml 3 Mar 2003 01:07:03 -0000 1.4 --- manipulating_data.xml 3 Mar 2003 06:39:11 -0000 1.5 *************** *** 427,439 **** their state also updated. (Except for lifecycle objects.) </para> - - <para> - Limitation: <literal>Session.update()</literal> may <emphasis>not</emphasis> be used on - objects that contain toplevel collections (including subcollections). - </para> <para> Hibernate users have requested a general purpose method that either saves a ! transient instance by generating a new identifier or updates the persistent state associated with its current identifier. The <literal>saveOrUpdate()</literal> method now implements this functionality. Hibernate distinguishes "new" (unsaved) --- 427,434 ---- their state also updated. (Except for lifecycle objects.) </para> <para> Hibernate users have requested a general purpose method that either saves a ! transient instance by generating a new identifier or update the persistent state associated with its current identifier. The <literal>saveOrUpdate()</literal> method now implements this functionality. Hibernate distinguishes "new" (unsaved) |
From: <tu...@us...> - 2003-03-03 06:17:56
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/pdf In directory sc8-pr-cvs1:/tmp/cvs-serv28648/pdf Modified Files: hibernate_reference.pdf Log Message: Re-generated Index: hibernate_reference.pdf =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/pdf/hibernate_reference.pdf,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** hibernate_reference.pdf 2 Mar 2003 13:59:01 -0000 1.4 --- hibernate_reference.pdf 3 Mar 2003 06:17:51 -0000 1.5 *************** *** 9,13 **** >> stream ! Gaq4K4V*-0$jPY'^S2q]f'@;ti(23_2pK=\38imP%R<G[s.4fc*Lc-8q]ma6C`PW('o%C(.,o2XalF3pPE6Y#V(#nDhnj]s10-OXTldNq0hP"=>m')u4:&S%:Bn+9Ou>g9.+4F/[<P8<Ta=*MHq85l_q7S]hS7glNV3)1]+hI4%R6CpqX7!-.+?RBL86_kG7MM@ei!mP>K_!oA$'?!^A.dW^bq_~> endstream endobj --- 9,13 ---- >> stream ! Gaq4K4V*-0$jPY'^S2q]f%tCR3"e'q9lk;/%S.)i!(=d*mjT+%TkWAr:X[+tf#&/#DMX9?N[$;P``^fC=Cu5g:<G#e>?L>uJRo?^-p4ST!i7/3hZ/.-%?,KBPC^RXP1H=87oh)2/RFT=BYk=l3i'9C@;I6$?bb@BNRdgf]+hI4%mO7Ao\Yk$.FSd7@8\kQ]Q4orZ*mfFfNO;>(b7J5n]_S"LGc+~> endstream [...7374 lines suppressed...] ! 0000377390 00000 n ! 0000377632 00000 n ! 0000377870 00000 n ! 0000377984 00000 n ! 0000378070 00000 n ! 0000378181 00000 n ! 0000378297 00000 n ! 0000378409 00000 n ! 0000378518 00000 n ! 0000378631 00000 n ! 0000378738 00000 n trailer << ! /Size 507 /Root 2 0 R /Info 4 0 R >> startxref ! 387675 %%EOF |
From: <tu...@us...> - 2003-03-03 06:17:16
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/src/xsl In directory sc8-pr-cvs1:/tmp/cvs-serv28590/src/xsl Modified Files: fopdf.xsl Log Message: Improved running headers Index: fopdf.xsl =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/xsl/fopdf.xsl,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** fopdf.xsl 23 Feb 2003 13:52:28 -0000 1.1 --- fopdf.xsl 3 Mar 2003 06:17:12 -0000 1.2 *************** *** 64,67 **** --- 64,80 ---- <!--################################################### + Header + ################################################### --> + + <!-- More space in the center header for long text --> + <xsl:attribute-set name="header.content.properties"> + <xsl:attribute name="font-family"> + <xsl:value-of select="$body.font.family"/> + </xsl:attribute> + <xsl:attribute name="margin-left">-5em</xsl:attribute> + <xsl:attribute name="margin-right">-5em</xsl:attribute> + </xsl:attribute-set> + + <!--################################################### Custom Footer ################################################### --> *************** *** 227,231 **** <xsl:param name="page.margin.top">5mm</xsl:param> <xsl:param name="region.before.extent">10mm</xsl:param> ! <xsl:param name="body.margin.top">15mm</xsl:param> <xsl:param name="body.margin.bottom">15mm</xsl:param> --- 240,244 ---- <xsl:param name="page.margin.top">5mm</xsl:param> <xsl:param name="region.before.extent">10mm</xsl:param> ! <xsl:param name="body.margin.top">10mm</xsl:param> <xsl:param name="body.margin.bottom">15mm</xsl:param> |
From: <tu...@us...> - 2003-03-03 06:16:53
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/images In directory sc8-pr-cvs1:/tmp/cvs-serv28450/images Modified Files: lite.svg Log Message: JTA instead of JDA Index: lite.svg =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/images/lite.svg,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** lite.svg 23 Feb 2003 13:50:31 -0000 1.1 --- lite.svg 3 Mar 2003 06:16:46 -0000 1.2 *************** *** 327,334 **** id="text414"> <tspan ! x="377.095947" ! y="179.154343" ! id="tspan419"> ! JDA</tspan> </text> </svg> --- 327,334 ---- id="text414"> <tspan ! x="377.096008" ! y="179.154999" ! id="tspan145"> ! JTA</tspan> </text> </svg> |
From: <one...@us...> - 2003-03-03 01:07:06
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/src In directory sc8-pr-cvs1:/tmp/cvs-serv9746/reference/src Modified Files: examples.xml manipulating_data.xml query_language.xml transactions.xml Log Message: documented latest QL changes Index: examples.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/examples.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** examples.xml 23 Feb 2003 13:53:24 -0000 1.4 --- examples.xml 3 Mar 2003 01:07:03 -0000 1.5 *************** *** 254,261 **** <mediaobject> <imageobject role="fo"> ! <imagedata fileref="images/AuthorWork.gif" format="GIF" align="center"/> </imageobject> <imageobject role="html"> ! <imagedata fileref="../images/AuthorWork.gif" format="GIF" align="center"/> </imageobject> </mediaobject> --- 254,261 ---- <mediaobject> <imageobject role="fo"> ! <imagedata fileref="images/CustomerOrderProduct.gif" format="GIF" align="center"/> </imageobject> <imageobject role="html"> ! <imagedata fileref="../images/CustomerOrderProduct.gif" format="GIF" align="center"/> </imageobject> </mediaobject> Index: manipulating_data.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/manipulating_data.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** manipulating_data.xml 23 Feb 2003 13:53:24 -0000 1.3 --- manipulating_data.xml 3 Mar 2003 01:07:03 -0000 1.4 *************** *** 96,100 **** <programlisting><![CDATA[List cats = sess.find( ! "from cat in class eg.Cat where cat.birthdate = ?", date, Hibernate.DATE --- 96,100 ---- <programlisting><![CDATA[List cats = sess.find( ! "from eg.Cat as cat where cat.birthdate = ?", date, Hibernate.DATE *************** *** 102,115 **** List mates = sess.find( ! "select mate from cat in class eg.Cat, cat in class eg.DomesticCat where " + ! "cat.mate = mate and cat.name = ?", name, Hibernate.STRING ); ! List cats = sess.find( "from cat in class eg.Cat where cat.mate.bithdate is null" ); List moreCats = sess.find( ! "from cat in class eg.Cat where " + "cat.name = 'Fritz' or cat.id = ? or cat.id = ?", new Object[] { id1, id2 }, --- 102,115 ---- List mates = sess.find( ! "select mate from eg.Cat as cat join cat.mate as mate " + ! "where cat.name = ?", name, Hibernate.STRING ); ! List cats = sess.find( "from eg.Cat as cat where cat.mate.bithdate is null" ); List moreCats = sess.find( ! "from eg.Cat as cat where " + "cat.name = 'Fritz' or cat.id = ? or cat.id = ?", new Object[] { id1, id2 }, *************** *** 118,122 **** List problems = sess.find( ! "from fish in class fish.GoldFish " + "where fish.birthday > fish.deceased or fish.birthday is null" );]]></programlisting> --- 118,122 ---- List problems = sess.find( ! "from fish.GoldFish as fish " + "where fish.birthday > fish.deceased or fish.birthday is null" );]]></programlisting> *************** *** 142,146 **** <programlisting><![CDATA[// fetch ids ! Iterator iter = sess.iterate("from q in class eg.Qux order by q.likeliness"); while ( iter.hasNext() ) { Qux qux = (Qux) iter.next(); // fetch the object --- 142,146 ---- <programlisting><![CDATA[// fetch ids ! Iterator iter = sess.iterate("from eg.Qux q order by q.likeliness"); while ( iter.hasNext() ) { Qux qux = (Qux) iter.next(); // fetch the object *************** *** 172,178 **** <programlisting><![CDATA[ Iterator iter = sess.iterate( ! "select customer, product from customer in class Customer, " + ! "product in class Product, " + ! "purchase in customer.purchases " + "where product = purchase.product" );]]></programlisting> --- 172,179 ---- <programlisting><![CDATA[ Iterator iter = sess.iterate( ! "select customer, product " + ! "from Customer customer, " + ! "Product product " + ! "join customer.purchases purchase " + "where product = purchase.product" );]]></programlisting> *************** *** 189,193 **** <programlisting><![CDATA[Iterator foosAndBars = sess.iterate( ! "select foo, bar from foo in class eg.Foo, bar in class eg.Bar" + "where bar.date = foo.date" ); --- 190,194 ---- <programlisting><![CDATA[Iterator foosAndBars = sess.iterate( ! "select foo, bar from eg.Foo foo, eg.Bar bar " + "where bar.date = foo.date" ); *************** *** 209,213 **** <programlisting><![CDATA[Iterator results = sess.iterate( ! "select cat.color, min(cat.birthdate), count(cat) from cat in class eg.Cat " + "group by cat.color" ); --- 210,214 ---- <programlisting><![CDATA[Iterator results = sess.iterate( ! "select cat.color, min(cat.birthdate), count(cat) from eg.Cat cat " + "group by cat.color" ); *************** *** 221,229 **** <programlisting><![CDATA[Iterator iter = sess.iterate( ! "select cat.type, cat.birthdate, cat.name from cat in class eg.DomesticCat" );]]></programlisting> <programlisting><![CDATA[List list = sess.find( ! "select cat, cat.mate.name from cat in class eg.DomesticCat" );]]></programlisting> --- 222,230 ---- <programlisting><![CDATA[Iterator iter = sess.iterate( ! "select cat.type, cat.birthdate, cat.name from eg.DomesticCat cat" );]]></programlisting> <programlisting><![CDATA[List list = sess.find( ! "select cat, cat.mate.name from eg.DomesticCat cat" );]]></programlisting> *************** *** 239,243 **** </para> ! <programlisting><![CDATA[Query q = sess.createQuery("from cat in class eg.DomesticCat"); q.setFirstResult(20); q.setMaxResults(10); --- 240,244 ---- </para> ! <programlisting><![CDATA[Query q = sess.createQuery("from eg.DomesticCat cat"); q.setFirstResult(20); q.setMaxResults(10); *************** *** 251,255 **** <programlisting><![CDATA[<query name="eg.DomesticCat.by.name.and.minimum.weight"><![CDATA[ ! from cat in class eg.DomesticCat where cat.name = ? and cat.weight > ? --- 252,256 ---- <programlisting><![CDATA[<query name="eg.DomesticCat.by.name.and.minimum.weight"><![CDATA[ ! from eg.DomesticCat as cat where cat.name = ? and cat.weight > ? *************** *** 290,298 **** </itemizedlist> ! <programlisting><![CDATA[Query q = sess.createQuery("from cat in class eg.DomesticCat where cat.name = :name"); q.setString("name", "Fritz"); Iterator cats = q.iterate();]]></programlisting> ! <programlisting><![CDATA[Query q = sess.createQuery("from cat in class eg.DomesticCat where cat.name = ?"); q.setString(0, "PK"); Iterator cats = q.iterate();]]></programlisting> --- 291,299 ---- </itemizedlist> ! <programlisting><![CDATA[Query q = sess.createQuery("from eg.DomesticCat cat where cat.name = :name"); q.setString("name", "Fritz"); Iterator cats = q.iterate();]]></programlisting> ! <programlisting><![CDATA[Query q = sess.createQuery("from eg.DomesticCat cat where cat.name = ?"); q.setString(0, "PK"); Iterator cats = q.iterate();]]></programlisting> *************** *** 308,312 **** </para> ! <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from cat in class eg.DomesticCat " + "order by cat.name"); ScrollableResults cats = q.scroll(); --- 309,313 ---- </para> ! <programlisting><![CDATA[Query q = sess.createQuery("select cat.name, cat from eg.DomesticCat cat " + "order by cat.name"); ScrollableResults cats = q.scroll(); Index: query_language.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/query_language.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** query_language.xml 2 Mar 2003 13:03:15 -0000 1.5 --- query_language.xml 3 Mar 2003 01:07:03 -0000 1.6 *************** *** 165,169 **** <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from eg.Cat cat></programlisting> <para> --- 165,169 ---- <programlisting><![CDATA[select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from eg.Cat cat]]></programlisting> <para> *************** *** 332,336 **** <programlisting><![CDATA[store.owner.address.city //okay ! store.owner.address //error!]]></programlisting> </sect1> --- 332,336 ---- <programlisting><![CDATA[store.owner.address.city //okay ! store.owner.address //error!]]></programlisting> </sect1> *************** *** 412,416 **** <programlisting><![CDATA[from eg.DomesticCat cat where cat.name between 'A' and 'B' ! from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', Baz" )]]></programlisting> <para> --- 412,416 ---- <programlisting><![CDATA[from eg.DomesticCat cat where cat.name between 'A' and 'B' ! from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )]]></programlisting> <para> *************** *** 420,424 **** <programlisting><![CDATA[from eg.DomesticCat cat where cat.name not between 'A' and 'B' ! from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', Baz" )]]></programlisting> <para> --- 420,424 ---- <programlisting><![CDATA[from eg.DomesticCat cat where cat.name not between 'A' and 'B' ! from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )]]></programlisting> <para> *************** *** 610,614 **** <para> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). Even /correlated/ subqueries (subqueries that refer to an alias in the outer query) are allowed. </para> --- 610,614 ---- <para> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). Even correlated subqueries (subqueries that refer to an alias in the outer query) are allowed. </para> Index: transactions.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/transactions.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** transactions.xml 23 Feb 2003 13:53:24 -0000 1.3 --- transactions.xml 3 Mar 2003 01:07:03 -0000 1.4 *************** *** 231,236 **** fooList = s.find( ! "select foo from foo in class eg.Foo where foo.Date = current date" ! // uses db2 date function ); bar = (Bar) s.create(Bar.class); --- 231,236 ---- fooList = s.find( ! "select foo from eg.Foo foo where foo.Date = current date" ! // uses db2 date function ); bar = (Bar) s.create(Bar.class); |
From: <one...@us...> - 2003-03-03 01:07:06
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/html_single In directory sc8-pr-cvs1:/tmp/cvs-serv9746/reference/html_single Modified Files: index.html Log Message: documented latest QL changes Index: index.html =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/html_single/index.html,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** index.html 2 Mar 2003 13:59:01 -0000 1.5 --- index.html 3 Mar 2003 01:07:03 -0000 1.6 *************** *** 63,74 **** <tt class="literal">foo==bar</tt> </p></dd></dl></div><p> ! Then for objects returned by a <span class="emphasis"><em>particular</em></span> <tt class="literal">Session</tt>, ! the two notions are equivalent. However, while the application might concurrently access the "same" (persistent identity) business object in two different sessions, the two instances will actually be "different" (JVM identity). </p><p> ! This approach leaves Hibernate and the database to worry about concurrency (the application never needs to synchronize on any business object, as long as it sticks to a ! single thread per <tt class="literal">Session</tt>) or object identity (within a session the [...3099 lines suppressed...] ! particular transaction. </p></dd><dt><span class="term">In a three tiered architecture, consider using <tt class="literal">saveOrUpdate()</tt>.</span></dt><dd><p> When using a servlet / session bean architecture, you could pass persistent objects loaded in ! the session bean to and from the servlet / JSP layer. Use a new session to service each request. ! Use <tt class="literal">Session.update()</tt> or <tt class="literal">Session.saveOrUpdate()</tt> to update the persistent state of an object. </p></dd><dt><span class="term">In a two tiered architecture, consider using session disconnection.</span></dt><dd><p> *************** *** 3461,3465 **** remember to disconnect the session before returning control to the client. </p></dd><dt><span class="term">Don't treat exceptions as recoverable.</span></dt><dd><p> ! This is more of a necessary paractice than a "best" practice. When an exception occurs, roll back the <tt class="literal">Transaction</tt> and close the <tt class="literal">Session</tt>. If you don't, Hibernate can't guarantee that in-memory state accurately represents persistent state --- 3457,3461 ---- remember to disconnect the session before returning control to the client. </p></dd><dt><span class="term">Don't treat exceptions as recoverable.</span></dt><dd><p> ! This is more of a necessary paractice than a "best" practice. When an exception occurs, roll back the <tt class="literal">Transaction</tt> and close the <tt class="literal">Session</tt>. If you don't, Hibernate can't guarantee that in-memory state accurately represents persistent state |
From: <db...@us...> - 2003-03-02 15:30:26
|
Update of /cvsroot/hibernate/Hibernate2 In directory sc8-pr-cvs1:/tmp/cvs-serv23604 Modified Files: build.xml Log Message: added rar target to create JCA impl Index: build.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/build.xml,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** build.xml 1 Mar 2003 13:11:16 -0000 1.8 --- build.xml 2 Mar 2003 15:30:23 -0000 1.9 *************** *** 135,138 **** --- 135,150 ---- <jar jarfile="${dist.dir}/${jar.name}.jar" basedir="${build.dir}"/> </target> + + <target name="rar" depends="jar" description="Build a JCA distribution .rar file"> + <mkdir dir="jca"/> + <jar jarfile="jca/${jar.name}.rar" basedir="${dist.dir}"> + <fileset dir="${dist.dir}"> + <include name="${dist.dir}/${jar.name}.jar" /> + </fileset> + <fileset dir="${build.dir}"> + <include name="META-INF/ra.xml" /> + </fileset> + </jar> + </target> <target name="javadoc" description="Compile the Javadoc API documentation to dist dir"> |
From: <db...@us...> - 2003-03-02 15:29:22
|
Update of /cvsroot/hibernate/Hibernate2/lib In directory sc8-pr-cvs1:/tmp/cvs-serv23091/lib Added Files: connector.jar Log Message: initial commit of JCA 1.0 impl --- NEW FILE: connector.jar --- (This appears to be a binary file; contents omitted.) |
From: <db...@us...> - 2003-03-02 15:28:32
|
Update of /cvsroot/hibernate/Hibernate2/src/META-INF In directory sc8-pr-cvs1:/tmp/cvs-serv22722/src/META-INF Added Files: ra.xml Log Message: initial commit of JCA 1.0 impl --- NEW FILE: ra.xml --- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE connector PUBLIC "-//Sun Microsystems, Inc.//DTD Connector 1.0//EN" "http://java.sun.com/dtd/connector_1_0.dtd"> <connector> <display-name>Hibernate Resource Adapter</display-name> <vendor-name>Hibernate</vendor-name> <spec-version>1.0</spec-version> <eis-type>Hibernate Sessions</eis-type> <version>0.9</version> <license> <description></description> <license-required></license-required> </license> <resourceadapter> <managedconnectionfactory-class>net.sf.hibernate.jca.ManagedConnectionFactoryImpl</managedconnectionfactory-class> <connectionfactory-interface>net.sf.hibernate.SessionFactory</connectionfactory-interface> <connectionfactory-impl-class>net.sf.hibernate.jca.JCASessionFactoryImpl</connectionfactory-impl-class> <connection-interface>net.sf.hibernate.Session</connection-interface> <connection-impl-class>net.sf.hibernate.impl.SessionImpl</connection-impl-class> <transaction-support>LocalTransaction</transaction-support> <config-property> <config-property-name>ConnectionURL</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>DriverClass</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>UserName</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>Password</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>Dialect</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>MapResources</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <authentication-mechanism> <description>BasicPassword</description> <authentication-mechanism-type>BasicPassword</authentication-mechanism-type> <credential-interface>javax.resource.security.PasswordCredential</credential-interface> </authentication-mechanism> <reauthentication-support>true</reauthentication-support> <security-permission> <description></description> <security-permission-spec> </security-permission-spec> </security-permission> </resourceadapter> </connector> |
From: <db...@us...> - 2003-03-02 15:28:16
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/jca In directory sc8-pr-cvs1:/tmp/cvs-serv22624/src/net/sf/hibernate/jca Added Files: JCASessionImpl.java ManagedConnectionImpl.java JCASessionFactoryImpl.java LocalTransactionImpl.java ManagedConnectionFactoryImpl.java MetaDataImpl.java ConnectionRequestInfoImpl.java hibernate-service.xml Log Message: initial commit of JCA 1.0 impl --- NEW FILE: JCASessionImpl.java --- // $Id$ package net.sf.hibernate.jca; import java.io.Serializable; import java.sql.Connection; import java.util.Collection; import java.util.Iterator; import java.util.List; import net.sf.hibernate.FlushMode; import net.sf.hibernate.HibernateException; import net.sf.hibernate.LockMode; import net.sf.hibernate.Query; import net.sf.hibernate.Session; import net.sf.hibernate.Transaction; import net.sf.hibernate.type.Type; public class JCASessionImpl implements Session { private Session session; private ManagedConnectionImpl mc; public JCASessionImpl(Session session, ManagedConnectionImpl mc){ this.session = session; this.mc = mc; } public void flush() throws HibernateException { session.flush(); } public void setFlushMode(FlushMode flushMode) { session.setFlushMode(flushMode); } public FlushMode getFlushMode() { return session.getFlushMode(); } public Connection connection() throws HibernateException { return session.connection(); } public Connection disconnect() throws HibernateException { return session.disconnect(); } public void reconnect() throws HibernateException { session.reconnect(); } public void reconnect(Connection connection) throws HibernateException { session.reconnect(connection); } public Connection close() throws HibernateException { mc.closeHandle(this); mc = null; return session.close(); } public boolean isOpen() { return session.isOpen(); } /** * @see net.sf.hibernate.Session#isConnected() */ public boolean isConnected() { return session.isConnected(); } /** * @see net.sf.hibernate.Session#getIdentifier(Object) */ public Serializable getIdentifier(Object object) throws HibernateException { return session.getIdentifier(object); } /** * @see net.sf.hibernate.Session#load(Class, Serializable, LockMode) */ public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException { return session.load(theClass, id, lockMode); } /** * @see net.sf.hibernate.Session#load(Class, Serializable) */ public Object load(Class theClass, Serializable id) throws HibernateException { return session.load(theClass, id); } /** * @see net.sf.hibernate.Session#load(Object, Serializable) */ public void load(Object object, Serializable id) throws HibernateException { session.load(object, id); } /** * @see net.sf.hibernate.Session#save(Object) */ public Serializable save(Object object) throws HibernateException { return session.save(object); } /** * @see net.sf.hibernate.Session#save(Object, Serializable) */ public void save(Object object, Serializable id) throws HibernateException { session.save(object, id); } /** * @see net.sf.hibernate.Session#saveOrUpdate(Object) */ public void saveOrUpdate(Object object) throws HibernateException { session.saveOrUpdate(object); } /** * @see net.sf.hibernate.Session#update(Object) */ public void update(Object object) throws HibernateException { session.update(object); } /** * @see net.sf.hibernate.Session#update(Object, Serializable) */ public void update(Object object, Serializable id) throws HibernateException { session.update(object, id); } public void delete(Object object) throws HibernateException { session.delete(object); } public List find(String query) throws HibernateException { return session.find(query); } public List find(String query, Object value, Type type) throws HibernateException { return session.find(query, value, type); } public List find(String query, Object[] values, Type[] types) throws HibernateException { return session.find(query, values, types); } public Iterator iterate(String query) throws HibernateException { return session.iterate(query); } public Iterator iterate(String query, Object value, Type type) throws HibernateException { return session.iterate(query, value, type); } public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException { return session.iterate(query, values, types); } public Collection filter(Object collection, String filter) throws HibernateException { return session.filter(collection, filter); } public Collection filter( Object collection, String filter, Object value, Type type) throws HibernateException { return null; } public Collection filter( Object collection, String filter, Object[] values, Type[] types) throws HibernateException { return session.filter(collection, filter, values, types); } public int delete(String query) throws HibernateException { return session.delete(query); } public int delete(String query, Object value, Type type) throws HibernateException { return session.delete(query, value, type); } public int delete(String query, Object[] values, Type[] types) throws HibernateException { return session.delete(query, values, types); } public void lock(Object object, LockMode lockMode) throws HibernateException { session.lock(object, lockMode); } public void refresh(Object object) throws HibernateException { session.refresh(object); } public LockMode getCurrentLockMode(Object object) throws HibernateException { return session.getCurrentLockMode(object); } public Transaction beginTransaction() throws HibernateException { return session.beginTransaction(); } public Query createQuery(String queryString) throws HibernateException { return session.createQuery(queryString); } public Query createFilter(Object collection, String queryString) throws HibernateException { return session.createFilter(collection, queryString); } public Query getNamedQuery(String queryName) throws HibernateException { return session.getNamedQuery(queryName); } void setManagedConnection(ManagedConnectionImpl mc){ this.mc = mc; } } --- NEW FILE: ManagedConnectionImpl.java --- // $Id$ package net.sf.hibernate.jca; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; import java.util.Set; import javax.resource.NotSupportedException; import javax.resource.ResourceException; import javax.resource.spi.ConnectionEvent; import javax.resource.spi.ConnectionEventListener; import javax.resource.spi.ConnectionRequestInfo; import javax.resource.spi.IllegalStateException; import javax.resource.spi.LocalTransaction; import javax.resource.spi.ManagedConnection; import javax.resource.spi.ManagedConnectionFactory; import javax.resource.spi.ManagedConnectionMetaData; import javax.security.auth.Subject; import javax.transaction.xa.XAResource; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Implementation of JCA Managed Connection. The underlying connection is a java.sql.Connecion object * which is passed to a Hibernate session object for the client to use. * * This is based on a JBoss LPGL generic JDBC JCA implementation * * Currently only supports LocalTransactions (XA should follow at some stage) * */ public class ManagedConnectionImpl implements ManagedConnection { private static final Log log = LogFactory.getLog(ManagedConnectionImpl.class); // true if connection has been destroyed private boolean destroyed; // the factory that created this managed connection private ManagedConnectionFactory mcf; // as per JCA 1.0 spec 5.6 when this is not null then logging has been enabled // by the application server and we log to this writer private PrintWriter logWriter; // factory to create sessions private SessionFactory sessions; // underlying connection to the database private Connection connection; // registered listeners from the application server private final Collection listeners = new ArrayList(); // a set of JCASessionImpl handles associated with this managed connection private final Set handles = new HashSet(); private Properties props; ManagedConnectionImpl( ManagedConnectionFactory mcf, String user, Properties props, SessionFactory sessions, Connection connection) { log.trace("Constructor called with user " + user); this.mcf = mcf; this.sessions = sessions; this.connection = connection; this.props = props; } /** * Creates and returns a new Hibernate Session * * Will throw a ResourceException if the session factory * fails to create a session */ public Object getConnection( Subject subject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException { log.trace( "getConnection called with subject[" + subject + " ] connection request info[" + connectionRequestInfo + "]"); // maybe should check the credentials match up with the current connection? // create session from the session factory Session session = null; try { session = sessions.openSession(connection); } catch (Exception hbe) { log.error( "Error opening session with connection " + connection, hbe); throw new ResourceException(hbe.getMessage()); } JCASessionImpl jcaSession = new JCASessionImpl(session, this); // add the session handle to the collection of handles on this connection synchronized (handles) { handles.add(jcaSession); } if (log.isDebugEnabled()) { log.debug( "Added session handle - " + jcaSession + " to handles now at size " + handles.size()); } return jcaSession; } /** * Closes the connection to the database * * @throws ResourceException cannot close connection (with the linked exception) */ public void destroy() throws ResourceException { if (log.isTraceEnabled()) { log.trace("destroy called on " + this); } if (connection == null) throw new IllegalStateException("Resource cannot be destroyed because it is null"); try { if (connection.isClosed()) throw new IllegalStateException("Resource cannot be destroyed because it is already closed"); connection.close(); connection = null; } catch (SQLException ex) { log.error("Error closing connection - " + connection, ex); ResourceException re = new ResourceException("Exception trying to close connection"); re.setLinkedException(ex); throw re; } finally { destroyed = true; } } /** * Cleans up connection handles so they can't be used again * But the physical connection is kept open */ public void cleanup() throws ResourceException { if (log.isTraceEnabled()) { log.trace("cleanup called on " + this); } synchronized (handles) { for (Iterator i = handles.iterator(); i.hasNext();) { JCASessionImpl lc = (JCASessionImpl) i.next(); lc.setManagedConnection(null); } handles.clear(); } } /** * Associates the session handle with this managed connection */ public void associateConnection(Object handle) throws ResourceException { if (!(handle instanceof JCASessionImpl)) { throw new ResourceException( "Wrong kind of connection handle to associate " + handle); } ((JCASessionImpl) handle).setManagedConnection(this); synchronized (handles) { handles.add(handle); } } public void addConnectionEventListener(ConnectionEventListener listener) { synchronized (listeners) { listeners.add(listener); } } public void removeConnectionEventListener(ConnectionEventListener listener) { synchronized (listeners) { listeners.remove(listener); } } /** * NOT SUPPORTED * @throws NotSupportedException */ public XAResource getXAResource() throws ResourceException { throw new NotSupportedException("XA transaction not supported"); } public LocalTransaction getLocalTransaction() throws ResourceException { return new LocalTransactionImpl(this); } public ManagedConnectionMetaData getMetaData() throws ResourceException { return new MetaDataImpl(this); } public void setLogWriter(PrintWriter out) throws ResourceException { this.logWriter = out; } public PrintWriter getLogWriter() throws ResourceException { return logWriter; } public Properties getProps() { return props; } public void setProps(Properties props) { this.props = props; } // package private level methods ManagedConnectionFactory getManagedConnectionFactory() { return mcf; } void closeHandle(Session handle) { // remove the handle from the collection safely synchronized (handles) { handles.remove(handle); } // create a connection closed event and send ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED); ce.setConnectionHandle(handle); sendEvent(ce); } Connection getConnection() { return connection; } void sendEvent(final ConnectionEvent event) { int type = event.getId(); if (log.isDebugEnabled()) { log.debug("Sending connection event: " + type); } // convert to an array to avoid concurrent modification exceptions ConnectionEventListener[] list = (ConnectionEventListener[]) listeners.toArray( new ConnectionEventListener[listeners.size()]); for (int i = 0; i < list.length; i++) { switch (type) { case ConnectionEvent.CONNECTION_CLOSED : list[i].connectionClosed(event); break; case ConnectionEvent.LOCAL_TRANSACTION_STARTED : list[i].localTransactionStarted(event); break; case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED : list[i].localTransactionCommitted(event); break; case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK : list[i].localTransactionRolledback(event); break; case ConnectionEvent.CONNECTION_ERROR_OCCURRED : list[i].connectionErrorOccurred(event); break; default : throw new IllegalArgumentException( "Illegal eventType: " + type); } } } } --- NEW FILE: JCASessionFactoryImpl.java --- //$Id: SessionImpl.java,v 1.22 2003/02/19 02:02:10 oneovthafew Exp $ package net.sf.hibernate.jca; import java.sql.Connection; import java.util.Map; import java.util.Properties; import javax.naming.NamingException; import javax.naming.Reference; import javax.resource.Referenceable; import javax.resource.ResourceException; import javax.resource.spi.ConnectionManager; import javax.resource.spi.ConnectionRequestInfo; import javax.resource.spi.ManagedConnectionFactory; import net.sf.hibernate.Databinder; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Interceptor; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.cfg.Configuration; import net.sf.hibernate.cfg.Environment; import net.sf.hibernate.metadata.ClassMetadata; import net.sf.hibernate.metadata.CollectionMetadata; import net.sf.hibernate.util.PropertiesHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public final class JCASessionFactoryImpl implements SessionFactory, Referenceable { private static final Log log = LogFactory.getLog(JCASessionFactoryImpl.class); private SessionFactory factory; private ManagedConnectionFactory managedFactory; private ConnectionManager cxManager; private Reference reference; public JCASessionFactoryImpl(ManagedConnectionFactory mcf, String dialect, String mapResources) throws HibernateException { this(mcf, null, dialect, mapResources); } public JCASessionFactoryImpl( ManagedConnectionFactory managedFactory, ConnectionManager cxManager, String dialect, String mapResources) throws HibernateException { Properties hibProperties = new Properties(); hibProperties.setProperty(Environment.DIALECT, dialect); Configuration cfg = new Configuration().addProperties(hibProperties); // taken from HibernateService, maybe factor out for JCA 1.5 String[] mappingFiles = PropertiesHelper.toStringArray(mapResources, " ,\n\t\r\f"); for ( int i=0; i<mappingFiles.length; i++ ) { cfg.addResource( mappingFiles[i], Thread.currentThread().getContextClassLoader() ); } this.managedFactory = managedFactory; this.factory = cfg.buildSessionFactory(); this.cxManager = cxManager; } public void close() throws HibernateException { factory.close(); } public Map getAllClassMetadata() throws HibernateException { return factory.getAllClassMetadata(); } public Map getAllCollectionMetadata() throws HibernateException { return factory.getAllCollectionMetadata(); } public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException { return factory.getClassMetadata(persistentClass); } public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException { return factory.getCollectionMetadata(roleName); } public Databinder openDatabinder() throws HibernateException { return factory.openDatabinder(); } public Session openSession() throws HibernateException { Session result = null; try { ConnectionRequestInfo info = new ConnectionRequestInfoImpl(factory); result = (Session) cxManager.allocateConnection(managedFactory, info); } catch (ResourceException re) { throw new HibernateException(re); } return result; } public Session openSession( Connection connection, Interceptor interceptor) { return factory.openSession(connection, interceptor); } public Session openSession(Connection connection) { return factory.openSession(connection); } public Session openSession(Interceptor interceptor) throws HibernateException { return factory.openSession(interceptor); } public Reference getReference() throws NamingException { return reference; } public void setReference(Reference ref) { reference = ref; } } --- NEW FILE: LocalTransactionImpl.java --- // $Id$ package net.sf.hibernate.jca; import java.sql.SQLException; import javax.jms.JMSException; import javax.resource.ResourceException; import javax.resource.spi.ConnectionEvent; import javax.resource.spi.EISSystemException; import javax.resource.spi.LocalTransaction; /** * Simple implementation of a location transaction for the moment. * * Basically delagates to the connection for commit and rollback * * Will set autocommit to false on the begin() * * Must clarify the Exception handling / messages / linked exceptions still */ public class LocalTransactionImpl implements LocalTransaction { protected ManagedConnectionImpl mc; public LocalTransactionImpl(final ManagedConnectionImpl mc) { this.mc = mc; } public void begin() throws ResourceException { try { mc.getConnection().setAutoCommit(false); } catch (SQLException ex) { ResourceException re = new EISSystemException( "Could not begin LocalTransaction : " + ex.getMessage()); re.setLinkedException(ex); throw re; } } public void commit() throws ResourceException { try { mc.getConnection().commit(); } catch (SQLException ex) { ResourceException re = new EISSystemException( "Could not commit LocalTransaction : " + ex.getMessage()); re.setLinkedException(ex); throw re; } } public void rollback() throws ResourceException { try { mc.getConnection().rollback(); } catch (SQLException ex) { ResourceException re = new EISSystemException( "Could not rollback LocalTransaction : " + ex.getMessage()); re.setLinkedException(ex); throw re; } } } --- NEW FILE: ManagedConnectionFactoryImpl.java --- package net.sf.hibernate.jca; import java.io.PrintWriter; import java.io.Serializable; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.util.Iterator; import java.util.Properties; import java.util.Set; import javax.resource.NotSupportedException; import javax.resource.ResourceException; import javax.resource.spi.ConnectionManager; import javax.resource.spi.ConnectionRequestInfo; import javax.resource.spi.ManagedConnection; import javax.resource.spi.ManagedConnectionFactory; import javax.resource.spi.security.PasswordCredential; import javax.security.auth.Subject; import net.sf.hibernate.HibernateException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Factory for creating Factories, connections and matching connections * * Does not currently support unmanaged environments */ public class ManagedConnectionFactoryImpl implements ManagedConnectionFactory, Serializable { private static final Log log = LogFactory.getLog(ManagedConnectionFactoryImpl.class); private String connectionURL; private String driverClass; private String userName; private String password; private int transactionIsolation = -1; private String dialect; private String mapResources; private Properties connectionProperties = new Properties(); private PrintWriter out; private boolean driverLoaded; public ManagedConnectionFactoryImpl() { } /** * Creates a Hibernate SessionFactory for the container * * @throws ResourceException can't create Session Factory (thrown with linked exception) */ public Object createConnectionFactory(ConnectionManager cxManager) throws ResourceException { log("createConnectionFactory with connection manager - " + cxManager); Object obj = null; try { obj = new JCASessionFactoryImpl(this, cxManager, dialect, mapResources); } catch (HibernateException hbe) { log( "Got Hibernate exception when trying to create Connection Factory", hbe); ResourceException re = new ResourceException("Got Hibernate exception when trying to create Connection Factory"); re.setLinkedException(hbe); throw re; } return obj; } /** * NOT SUPPORTED * * @throws NotSupportedException Unmanaged environments are not currently supported */ public Object createConnectionFactory() throws ResourceException { throw new NotSupportedException("Resource Adapter does not support an un-managed environment"); } /** * Creates a ManagedConnection and physically a connection to the database * * Currently only uses username, password, driver class and URL * * Need to include mapping files, isolation level, dialect etc * * @throws ResourceException cannot get connection to database */ public ManagedConnection createManagedConnection( Subject subject, ConnectionRequestInfo info) throws ResourceException { log("createManagedConnection called"); try { // Also taken from JBoss JDBC JCA Impl Properties props = getConnectionProperties(subject, info); // Some friendly drivers (Oracle, you guessed right) modify the props you supply. // Since we use our copy to identify compatibility in matchManagedConnection, we need // a pristine copy for our own use. So give the friendly driver a copy. Properties copy = new Properties(); copy.putAll(props); String url = internalGetConnectionURL(); checkDriver(url); Connection con = DriverManager.getConnection(url, copy); // wait for the begin transaction to turn auto commit off? //con.setAutoCommit(false); return new ManagedConnectionImpl( this, userName, props, ((ConnectionRequestInfoImpl) info).getSessionFactory(), con); } catch (Exception ex) { log("Got exception when trying to create Managed Connection", ex); ResourceException re = new ResourceException("Got exception when trying to create Managed Connection"); re.setLinkedException(ex); throw re; } } public void setLogWriter(PrintWriter out) throws ResourceException { this.out = out; } public PrintWriter getLogWriter() throws ResourceException { return this.out; } public ManagedConnection matchManagedConnections( Set mcs, Subject subject, ConnectionRequestInfo cri) throws ResourceException { Properties newProps = getConnectionProperties(subject, cri); for (Iterator i = mcs.iterator(); i.hasNext();) { Object o = i.next(); if (o instanceof ManagedConnectionImpl) { ManagedConnectionImpl mc = (ManagedConnectionImpl) o; if (mc.getProps().equals(newProps) /*&& mc.checkValid()*/ ) // JBoss method to check validity of connection by executing some SQL { return mc; } // end of if () } // end of if () } // end of for () return null; } /** * * @return hashcode computed according to recommendations in Effective Java. */ public int hashCode() { int result = 17; result = result * 37 + ((connectionURL == null) ? 0 : connectionURL.hashCode()); result = result * 37 + ((driverClass == null) ? 0 : driverClass.hashCode()); result = result * 37 + ((userName == null) ? 0 : userName.hashCode()); result = result * 37 + ((password == null) ? 0 : password.hashCode()); result = result * 37 + ((dialect == null) ? 0 : dialect.hashCode()); result = result * 37 + ((mapResources == null) ? 0 : mapResources.hashCode()); result = result * 37 + transactionIsolation; return result; } /** * * @param param1 <description> * @return <description> */ public boolean equals(Object other) { if (this == other) { return true; } // end of if () if (getClass() != other.getClass()) { return false; } // end of if () ManagedConnectionFactoryImpl otherMcf = (ManagedConnectionFactoryImpl) other; return this.connectionURL.equals(otherMcf.connectionURL) && this.driverClass.equals(otherMcf.driverClass) && ((this.mapResources == null) ? otherMcf.mapResources == null : this.mapResources.equals(otherMcf.mapResources)) && ((this.dialect == null) ? otherMcf.dialect == null : this.dialect.equals(otherMcf.dialect)) && ((this.userName == null) ? otherMcf.userName == null : this.userName.equals(otherMcf.userName)) && ((this.password == null) ? otherMcf.password == null : this.password.equals(otherMcf.password)) && this.transactionIsolation == otherMcf.transactionIsolation; } public String getDriverClass() { return driverClass; } public String getPassword() { return password; } public String getUserName() { return userName; } public void setDriverClass(String driverClass) { this.driverClass = driverClass; this.driverLoaded = false; } public void setPassword(String password) { this.password = password; } public void setUserName(String username) { this.userName = username; } public String getConnectionURL() { return connectionURL; } public void setConnectionURL(String url) { this.connectionURL = url; } public String getDialect() { return dialect; } public void setDialect(String dialect) { this.dialect = dialect; } public String getMapResources() { return mapResources; } public void setMapResources(String mapResources) { this.mapResources = mapResources; } public Properties getConnectionProperties() { return connectionProperties; } public void setConnectionProperties(Properties connectionProperties) { this.connectionProperties = connectionProperties; } public String getTransactionIsolation() { switch (this.transactionIsolation) { case Connection.TRANSACTION_NONE : return "TRANSACTION_NONE"; case Connection.TRANSACTION_READ_COMMITTED : return "TRANSACTION_READ_COMMITTED"; case Connection.TRANSACTION_READ_UNCOMMITTED : return "TRANSACTION_READ_UNCOMMITTED"; case Connection.TRANSACTION_REPEATABLE_READ : return "TRANSACTION_REPEATABLE_READ"; case Connection.TRANSACTION_SERIALIZABLE : return "TRANSACTION_SERIALIZABLE"; case -1 : return "DEFAULT"; default : return Integer.toString(transactionIsolation); } } public void setTransactionIsolation(String transactionIsolation) { if (transactionIsolation.equals("TRANSACTION_NONE")) { this.transactionIsolation = Connection.TRANSACTION_NONE; } else if (transactionIsolation.equals("TRANSACTION_READ_COMMITTED")) { this.transactionIsolation = Connection.TRANSACTION_READ_COMMITTED; } else if ( transactionIsolation.equals("TRANSACTION_READ_UNCOMMITTED")) { this.transactionIsolation = Connection.TRANSACTION_READ_UNCOMMITTED; } else if ( transactionIsolation.equals("TRANSACTION_REPEATABLE_READ")) { this.transactionIsolation = Connection.TRANSACTION_REPEATABLE_READ; } else if (transactionIsolation.equals("TRANSACTION_SERIALIZABLE")) { this.transactionIsolation = Connection.TRANSACTION_SERIALIZABLE; } else { try { this.transactionIsolation = Integer.parseInt(transactionIsolation); } catch (NumberFormatException nfe) { throw new IllegalArgumentException( "Setting Isolation level to unknown state: " + transactionIsolation); } } } private void log(String message) { log(message, null); } private void log(String message, Throwable t) { // log to provided output if set by app server // assumes to log error if an exception is provided if (out != null) { out.write(message); if (t != null) t.printStackTrace(out); } if (t != null) { log.error(message, t); } else { log.info(message); } } // taken from JBoss JCA impl /** * Check the driver for the given URL. If it is not registered already * then register it. * * @param url The JDBC URL which we need a driver for. */ protected void checkDriver(final String url) throws ResourceException { // don't bother if it is loaded already if (driverLoaded) { return; } log.debug("Checking driver for URL: " + url); if (driverClass == null) { throw new ResourceException("No Driver class specified!"); } // Check if the driver is already loaded, if not then try to load it if (isDriverLoadedForURL(url)) { driverLoaded = true; return; } // end of if () try { //try to load the class... this should register with DriverManager. Class clazz = Thread.currentThread().getContextClassLoader().loadClass( driverClass); if (isDriverLoadedForURL(url)) { driverLoaded = true; //return immediately, some drivers (Cloudscape) do not let you create an instance. return; } // end of if () //We loaded the class, but either it didn't register //and is not spec compliant, or is the wrong class. Driver driver = (Driver) clazz.newInstance(); DriverManager.registerDriver(driver); if (isDriverLoadedForURL(url)) { driverLoaded = true; return; } // end of if () //We can even instantiate one, it must be the wrong class for the URL. } catch (Exception e) { ResourceException re = new ResourceException( "Failed to register driver for: " + driverClass); re.setLinkedException(e); throw re; } throw new ResourceException( "Apparently wrong driver class specified for URL: class: " + driverClass + ", url: " + url); } private boolean isDriverLoadedForURL(String url) { try { DriverManager.getDriver(url); log.debug("Driver already registered for url: " + url); return true; } catch (Exception e) { log.debug("Driver not yet registered for url: " + url); return false; } // end of try-catch } protected String internalGetConnectionURL() { return connectionURL; } /** * Gets full set of connection properties, i.e. whatever is provided * in config plus "user" and "password" from subject/cri. * * <p>Note that the set is used to match connections to datasources as well * as to create new managed connections. * * <p>In fact, we have a problem here. Theoretically, there is a possible * name collision between config properties and "user"/"password". */ protected Properties getConnectionProperties( Subject subject, ConnectionRequestInfo cri) throws ResourceException { if (cri != null && cri.getClass() != ConnectionRequestInfoImpl.class) { throw new ResourceException( "Wrong kind of ConnectionRequestInfo: " + cri.getClass()); } // end of if () Properties props = new Properties(); props.putAll(connectionProperties); if (subject != null) { for (Iterator i = subject.getPrivateCredentials().iterator(); i.hasNext(); ) { Object o = i.next(); if (o instanceof PasswordCredential && ((PasswordCredential) o) .getManagedConnectionFactory() .equals( this)) { PasswordCredential cred = (PasswordCredential) o; props.setProperty( "user", (cred.getUserName() == null) ? "" : cred.getUserName()); props.setProperty( "password", new String(cred.getPassword())); return props; } // end of if () } // end of for () throw new ResourceException("No matching credentials in Subject!"); } // end of if () ConnectionRequestInfoImpl lcri = (ConnectionRequestInfoImpl) cri; if (lcri != null) { props.setProperty( "user", (lcri.getUserName() == null) ? "" : lcri.getUserName()); props.setProperty( "password", (lcri.getPassword() == null) ? "" : lcri.getPassword()); return props; } // end of if () if (userName != null) { props.setProperty("user", userName); props.setProperty("password", (password == null) ? "" : password); } return props; } } --- NEW FILE: MetaDataImpl.java --- package net.sf.hibernate.jca; import java.sql.SQLException; import javax.resource.ResourceException; import javax.resource.spi.EISSystemException; import javax.resource.spi.IllegalStateException; import javax.resource.spi.ManagedConnectionMetaData; /** * * Implementation delegates to the database connection meta data object * * All methods will throw IllegalStateException if the managed connection * has already been destroyed * */ public class MetaDataImpl implements ManagedConnectionMetaData { private ManagedConnectionImpl mc; public MetaDataImpl(ManagedConnectionImpl mc) { this.mc = mc; } public String getEISProductName() throws ResourceException { String result = null; try { result = mc.getConnection().getMetaData().getUserName(); } catch (SQLException e) { throw new EISSystemException(e.getMessage()); } return result; } public String getEISProductVersion() throws ResourceException { String result = null; try { result = mc.getConnection().getMetaData().getDriverVersion(); } catch (SQLException e) { throw new EISSystemException(e.getMessage()); } return result; } public int getMaxConnections() throws ResourceException { int result = 0; try { result = mc.getConnection().getMetaData().getMaxConnections(); } catch (SQLException e) { throw new EISSystemException(e.getMessage()); } return result; } public String getUserName() throws ResourceException { String result = null; try { result = mc.getConnection().getMetaData().getUserName(); } catch (SQLException e) { throw new EISSystemException(e.getMessage()); } return result; } } --- NEW FILE: ConnectionRequestInfoImpl.java --- package net.sf.hibernate.jca; import javax.resource.spi.ConnectionRequestInfo; import net.sf.hibernate.SessionFactory; public class ConnectionRequestInfoImpl implements ConnectionRequestInfo { private SessionFactory sessions; private String userName; private String password; public ConnectionRequestInfoImpl(SessionFactory sessions) { this.sessions = sessions; } public SessionFactory getSessionFactory(){ return sessions; } public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof ConnectionRequestInfoImpl) { ConnectionRequestInfoImpl other = (ConnectionRequestInfoImpl) obj; return (isEqual(this.sessions, other.sessions)); } else { return false; } } public int hashCode() { return sessions.hashCode(); } private boolean isEqual(Object o1, Object o2) { if (o1 == null) { return (o2 == null); } else { return o1.equals(o2); } } /** * Returns the password. * @return String */ public String getPassword() { return password; } /** * Returns the userName. * @return String */ public String getUserName() { return userName; } /** * Sets the password. * @param password The password to set */ public void setPassword(String password) { this.password = password; } /** * Sets the userName. * @param userName The userName to set */ public void setUserName(String userName) { this.userName = userName; } } --- NEW FILE: hibernate-service.xml --- <?xml version="1.0" encoding="UTF-8"?> <!-- ===================================================================== --> <!-- --> <!-- JBoss Server Configuration --> <!-- --> <!-- ===================================================================== --> <server> <!-- ==================================================================== --> <!-- New ConnectionManager setup for mysql using 2.0.11 driver --> <!-- Build jmx-api (build/build.sh all) and view for config documentation --> <!-- ==================================================================== --> <mbean code="org.jboss.resource.connectionmanager.LocalTxConnectionManager" name="jboss.jca:service=LocalTxCM,name=Hibernate Resource Adapter"> <attribute name="JndiName">jca/test</attribute> <depends optional-attribute-name="ManagedConnectionFactoryName"> <!--embedded mbean--> <mbean code="org.jboss.resource.connectionmanager.RARDeployment" name="jboss.jca:service=LocalTxDS,name=Hibernate Resource Adapter"> <attribute name="ManagedConnectionFactoryProperties"> <properties> <config-property> <config-property-name>ConnectionURL</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>jdbc:mysql:///test</config-property-value> </config-property> <config-property> <config-property-name>DriverClass</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>com.mysql.jdbc.Driver</config-property-value> </config-property> <config-property> <config-property-name>Password</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value></config-property-value> </config-property> <config-property> <config-property-name>UserName</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>dbradby</config-property-value> </config-property> <config-property> <config-property-name>Dialect</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>net.sf.hibernate.dialect.MySQLDialect</config-property-value> </config-property> <config-property> <config-property-name>MapResources</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>Simple.hbm.xml</config-property-value> </config-property> </properties> </attribute> <!--Below here are advanced properties --> <!--hack--> <depends optional-attribute-name="OldRarDeployment">jboss.jca:service=RARDeployment,name=Hibernate Resource Adapter</depends> </mbean> </depends> <depends optional-attribute-name="ManagedConnectionPool"> <!--embedded mbean--> <mbean code="org.jboss.resource.connectionmanager.JBossManagedConnectionPool" name="jboss.jca:service=LocalTxPool,name=Hibernate Resource Adapter"> <attribute name="MinSize">0</attribute> <attribute name="MaxSize">50</attribute> <attribute name="BlockingTimeoutMillis">5000</attribute> <attribute name="IdleTimeoutMinutes">15</attribute> <!--criteria indicates if Subject (from security domain) or app supplied parameters (such as from getConnection(user, pw)) are used to distinguish connections in the pool. Choices are ByContainerAndApplication (use both), ByContainer (use Subject), ByApplication (use app supplied params only), ByNothing (all connections are equivalent, usually if adapter supports reauthentication)--> <attribute name="Criteria">ByContainer</attribute> </mbean> </depends> <depends optional-attribute-name="CachedConnectionManager">jboss.jca:service=CachedConnectionManager</depends> <depends optional-attribute-name="JaasSecurityManagerService">jboss.security:service=JaasSecurityManager</depends> <!--make the rar deploy! hack till better deployment--> <depends>jboss.jca:service=RARDeployer</depends> <attribute name="TransactionManager">java:/TransactionManager</attribute> </mbean> </server> |
From: <db...@us...> - 2003-03-02 15:26:55
|
Update of /cvsroot/hibernate/Hibernate2/src/META-INF In directory sc8-pr-cvs1:/tmp/cvs-serv22137/src/META-INF Log Message: Directory /cvsroot/hibernate/Hibernate2/src/META-INF added to the repository |
From: <db...@us...> - 2003-03-02 15:26:35
|
Update of /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/jca In directory sc8-pr-cvs1:/tmp/cvs-serv22052/src/net/sf/hibernate/jca Log Message: Directory /cvsroot/hibernate/Hibernate2/src/net/sf/hibernate/jca added to the repository |
From: <tu...@us...> - 2003-03-02 13:59:05
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/html_single In directory sc8-pr-cvs1:/tmp/cvs-serv23405/doc/reference/html_single Modified Files: index.html Log Message: Version Update for Release Index: index.html =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/html_single/index.html,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** index.html 23 Feb 2003 13:45:24 -0000 1.4 --- index.html 2 Mar 2003 13:59:01 -0000 1.5 *************** *** 1,5 **** <html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> ! <title>HIBERNATE - Relational Persistence for Idiomatic Java</title><link rel="stylesheet" href="../style.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.60.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e1"></a>HIBERNATE - Relational Persistence for Idiomatic Java</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><p class="releaseinfo">2.0 beta2</p></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="#architecture">Architecture</a></dt><dd><dl><dt>1.1. <a href="#architecture-s1">Overview</a></dt><dt>1.2. <a href="#architecture-s2">Persistent Object Identity</a></dt><dt>1.3. <a href="#architecture-s3">JMX Integration</a></dt></dl></dd><dt>2. <a href="#session-configuration">SessionFactory Configuration</a></dt><dd><dl><dt>2.1. <a href="#session-configuration-s1">Programmatic Configuration</a></dt><dt>2.2. <a href="#session-configuration-s2">Obtaining a SessionFactory</a></dt><dt>2.3. <a href="#session-configuration-s3">User provided JDBC connection</a></dt><dt>2.4. <a href="#session-configuration-s4">Hibernate provided JDBC connection</a></dt><dt>2.5. <a href="#session-configuration-s5">Other properties</a></dt><dt>2.6. <a href="#session-configuration-s6">XML Configuration File</a></dt><dt>2.7. <a href="#session-configuration-s7">Logging</a></dt></dl></dd><dt>3. <a href="#persistent-classes">Persistent Classes</a></dt><dd><dl><dt>3.1. <a href="#persistent-classes-s1">Simple Example</a></dt><dd><dl><dt>3.1.1. <a href="#persistent-classes-s1-1">Declare accessors and mutators for persistent fields</a></dt><dt>3.1.2. <a href="#persistent-classes-s1-2">Implement a default constructor</a></dt><dt>3.1.3. <a href="#persistent-classes-s1-3">Provide an identifier property (optional)</a></dt></dl></dd><dt>3.2. <a href="#persistent-classes-s2">Inheritance</a></dt><dt>3.3. <a href="#persistent-classes-s3">Persistent Lifecycle Callbacks</a></dt><dt>3.4. <a href="#persistent-classes-s4">Validatable</a></dt></dl></dd><dt>4. <a href="#or-mapping">Basic O/R Mapping</a></dt><dd><dl><dt>4.1. <a href="#or-mapping-s1">Mapping declaration</a></dt><dd><dl><dt>4.1.1. <a href="#or-mapping-s1-1">Doctype</a></dt><dt>4.1.2. <a href="#or-mapping-s1-2">hibernate-mapping</a></dt><dt>4.1.3. <a href="#or-mapping-s1-3">class</a></dt><dt>4.1.4. <a href="#or-mapping-s1-4">id</a></dt><dt>4.1.5. <a href="#or-mapping-s1-4b">composite-id</a></dt><dt>4.1.6. <a href="#or-mapping-s1-5">discriminator</a></dt><dt>4.1.7. <a href="#or-mapping-s1-6">version (optional)</a></dt><dt>4.1.8. <a href="#or-mapping-s1-6b">timestamp (optional)</a></dt><dt>4.1.9. <a href="#or-mapping-s1-7">property</a></dt><dt>4.1.10. <a href="#or-mapping-s1-8">many-to-one</a></dt><dt>4.1.11. <a href="#or-mapping-s1-9">one-to-one</a></dt><dt>4.1.12. <a href="#or-mapping-s1-10">component, dynabean</a></dt><dt>4.1.13. <a href="#or-mapping-s1-11">subclass</a></dt><dt>4.1.14. <a href="#or-mapping-s1-11b">joined-subclass</a></dt><dt>4.1.15. <a href="#or-mapping-s1-12">map, set, list, bag</a></dt></dl></dd><dt>4.2. <a href="#or-mapping-s2">Hibernate Types</a></dt><dd><dl><dt>4.2.1. <a href="#or-mapping-s2-1">Entities and values</a></dt><dt>4.2.2. <a href="#or-mapping-s2-2">Basic value types</a></dt><dt>4.2.3. <a href="#or-mapping-s2-3">Persistent enum types</a></dt><dt>4.2.4. <a href="#or-mapping-s2-4">Custom value types</a></dt><dt>4.2.5. <a href="#or-mapping-s2-5">The object type</a></dt></dl></dd></dl></dd><dt>5. <a href="#adv-or-mapping">Advanced O/R Mapping</a></dt><dd><dl><dt>5.1. <a href="#adv-or-mapping-s1">Collections</a></dt><dd><dl><dt>5.1.1. <a href="#adv-or-mapping-s1-1">Persistent Collections</a></dt><dt>5.1.2. <a href="#adv-or-mapping-s1-3">Mapping a Collection</a></dt><dt>5.1.3. <a href="#adv-or-mapping-s1-5">Collections of Values and Many To Many Associations</a></dt><dt>5.1.4. <a href="#adv-or-mapping-s1-6">One To Many Associations</a></dt><dt>5.1.5. <a href="#adv-or-mapping-s1-7">Lazy Initialization</a></dt><dt>5.1.6. <a href="#adv-or-mapping-s1-8">Sorted Collections</a></dt><dt>5.1.7. <a href="#adv-or-mapping-s1-9">Garbage Collection</a></dt><dt>5.1.8. <a href="#adv-or-mapping-s1-10">Bidirectional Associations</a></dt><dt>5.1.9. <a href="#adv-or-mapping-s1-11">Ternary Associations</a></dt><dt>5.1.10. <a href="#adv-or-mapping-s1-12">Collection Example</a></dt></dl></dd><dt>5.2. <a href="#adv-or-mapping-s2">Components</a></dt><dd><dl><dt>5.2.1. <a href="#adv-or-mapping-s2-1">As Dependent Objects</a></dt><dt>5.2.2. <a href="#adv-or-mapping-s2-2">In Collections</a></dt><dt>5.2.3. <a href="#adv-or-mapping-s2-2b">As a Map Index</a></dt><dt>5.2.4. <a href="#adv-or-mapping-s2-3">As Composite Identifiers</a></dt><dt>5.2.5. <a href="#adv-or-mapping-s2-4">Dynabean components</a></dt></dl></dd><dt>5.3. <a href="#adv-or-mapping-s3">Cache</a></dt><dd><dl><dt>5.3.1. <a href="#adv-or-mapping-s3-1">Mapping</a></dt><dt>5.3.2. <a href="#adv-or-mapping-s3-2">Read Only Cache</a></dt><dt>5.3.3. <a href="#adv-or-mapping-s3-3">Read / Write Cache</a></dt></dl></dd><dt>5.4. <a href="#adv-or-mapping-s4">Proxies for Lazy Initialization</a></dt></dl></dd><dt>6. <a href="#manipulating-data">Manipulating Persistent Data</a></dt><dd><dl><dt>6.1. <a href="#manipulating-data-s1">Creating a persistent object</a></dt><dt>6.2. <a href="#manipulating-data-s2">Loading an object</a></dt><dt>6.3. <a href="#manipulating-data-s3">Querying</a></dt><dd><dl><dt>6.3.1. <a href="#manipulating-data-s4">Scalar queries</a></dt><dt>6.3.2. <a href="#manipulating-data-s5">The Query interface</a></dt><dt>6.3.3. <a href="#manipulating-data-s5b">Scrollable iteration</a></dt><dt>6.3.4. <a href="#manipulating-data-s6">Filtering collections</a></dt></dl></dd><dt>6.4. <a href="#manipulating-data-s7">Updating objects saved or loaded in the current session</a></dt><dt>6.5. <a href="#manipulating-data-s8">Updating objects saved or loaded in a previous session</a></dt><dt>6.6. <a href="#manipulating-data-s9">Deleting persistent objects</a></dt><dt>6.7. <a href="#manipulating-data-s10">Graphs of objects</a></dt><dd><dl><dt>6.7.1. <a href="#manipulating-data-s11a">Lifecycle objects</a></dt><dt>6.7.2. <a href="#manipulating-data-s11b">Persistence by Reachability</a></dt></dl></dd><dt>6.8. <a href="#manipulating-data-s12">Flushing</a></dt><dt>6.9. <a href="#manipulating-data-s13">Ending a Session</a></dt><dd><dl><dt>6.9.1. <a href="#manipulating-data-s13-1">Flushing the session</a></dt><dt>6.9.2. <a href="#manipulating-data-s13-2">Committing the transaction</a></dt><dt>6.9.3. <a href="#manipulating-data-s13-3">Closing the session</a></dt><dt>6.9.4. <a href="#manipulating-data-s13-4">Exception handling</a></dt></dl></dd><dt>6.10. <a href="#manipulating-data-s14">Interceptors</a></dt></dl></dd><dt>7. <a href="#query-language">Hibernate Query Language</a></dt><dd><dl><dt>7.1. <a href="#query-language-s1">Case Sensitivity</a></dt><dt>7.2. <a href="#query-language-s2">The from clause</a></dt><dt>7.3. <a href="#query-language-s3">The select clause</a></dt><dt>7.4. <a href="#query-language-s3b">polymorphism</a></dt><dt>7.5. <a href="#query-language-s4">from collections</a></dt><dt>7.6. <a href="#query-language-s5">The where clause</a></dt><dt>7.7. <a href="#query-language-s6">Expressions</a></dt><dt>7.8. <a href="#query-language-s7">The order by clause</a></dt><dt>7.9. <a href="#query-language-s8">The group by clause</a></dt><dt>7.10. <a href="#query-language-s9">Subqueries</a></dt></dl></dd><dt>8. <a href="#transactions">Transactions And Concurrency</a></dt><dd><dl><dt>8.1. <a href="#transactions-s1">Configurations, Sessions and Factories</a></dt><dt>8.2. <a href="#transactions-s2">Threads and connections</a></dt><dt>8.3. <a href="#transactions-s3">Optimistic Locking / Versioning</a></dt><dd><dl><dt>8.3.1. <a href="#transactions-s3-1">Long session with automatic versioning</a></dt><dt>8.3.2. <a href="#transactions-s3-2">Many sessions with automatic versioning</a></dt><dt>8.3.3. <a href="#transactions-s3-3">Application version checking</a></dt></dl></dd><dt>8.4. <a href="#transactions-s4">Session disconnection</a></dt><dt>8.5. <a href="#transactions-s5">Pessimistic Locking</a></dt></dl></dd><dt>9. <a href="#examples">Examples</a></dt><dd><dl><dt>9.1. <a href="#examples-s0">Employer/Employee</a></dt><dt>9.2. <a href="#examples-s1">Author/Work</a></dt><dt>9.3. <a href="#examples-s2">Customer/Order/Product</a></dt></dl></dd><dt>10. <a href="#best-practices">Best Practices</a></dt></dl></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="architecture"></a>Chapter 1. Architecture</h2></div></div><div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="architecture-s1"></a>1.1. Overview</h2></div></div><div></div></div><p> A (very) high-level view of the Hibernate architecture: </p><div class="mediaobject" align="center"><img src="../images/overview.gif" align="middle"></div><p> --- 1,5 ---- <html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> ! <title>HIBERNATE - Relational Persistence for Idiomatic Java</title><link rel="stylesheet" href="../style.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.60.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e1"></a>HIBERNATE - Relational Persistence for Idiomatic Java</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><p class="releaseinfo">2.0 beta4</p></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="#architecture">Architecture</a></dt><dd><dl><dt>1.1. <a href="#architecture-s1">Overview</a></dt><dt>1.2. <a href="#architecture-s2">Persistent Object Identity</a></dt><dt>1.3. <a href="#architecture-s3">JMX Integration</a></dt></dl></dd><dt>2. <a href="#session-configuration">SessionFactory Configuration</a></dt><dd><dl><dt>2.1. <a href="#session-configuration-s1">Programmatic Configuration</a></dt><dt>2.2. <a href="#session-configuration-s2">Obtaining a SessionFactory</a></dt><dt>2.3. <a href="#session-configuration-s3">User provided JDBC connection</a></dt><dt>2.4. <a href="#session-configuration-s4">Hibernate provided JDBC connection</a></dt><dt>2.5. <a href="#session-configuration-s5">Other properties</a></dt><dt>2.6. <a href="#session-configuration-s6">XML Configuration File</a></dt><dt>2.7. <a href="#session-configuration-s7">Logging</a></dt></dl></dd><dt>3. <a href="#persistent-classes">Persistent Classes</a></dt><dd><dl><dt>3.1. <a href="#persistent-classes-s1">Simple Example</a></dt><dd><dl><dt>3.1.1. <a href="#persistent-classes-s1-1">Declare accessors and mutators for persistent fields</a></dt><dt>3.1.2. <a href="#persistent-classes-s1-2">Implement a default constructor</a></dt><dt>3.1.3. <a href="#persistent-classes-s1-3">Provide an identifier property (optional)</a></dt></dl></dd><dt>3.2. <a href="#persistent-classes-s2">Inheritance</a></dt><dt>3.3. <a href="#persistent-classes-s3">Persistent Lifecycle Callbacks</a></dt><dt>3.4. <a href="#persistent-classes-s4">Validatable</a></dt></dl></dd><dt>4. <a href="#or-mapping">Basic O/R Mapping</a></dt><dd><dl><dt>4.1. <a href="#or-mapping-s1">Mapping declaration</a></dt><dd><dl><dt>4.1.1. <a href="#or-mapping-s1-1">Doctype</a></dt><dt>4.1.2. <a href="#or-mapping-s1-2">hibernate-mapping</a></dt><dt>4.1.3. <a href="#or-mapping-s1-3">class</a></dt><dt>4.1.4. <a href="#or-mapping-s1-4">id</a></dt><dt>4.1.5. <a href="#or-mapping-s1-4b">composite-id</a></dt><dt>4.1.6. <a href="#or-mapping-s1-5">discriminator</a></dt><dt>4.1.7. <a href="#or-mapping-s1-6">version (optional)</a></dt><dt>4.1.8. <a href="#or-mapping-s1-6b">timestamp (optional)</a></dt><dt>4.1.9. <a href="#or-mapping-s1-7">property</a></dt><dt>4.1.10. <a href="#or-mapping-s1-8">many-to-one</a></dt><dt>4.1.11. <a href="#or-mapping-s1-9">one-to-one</a></dt><dt>4.1.12. <a href="#or-mapping-s1-10">component, dynabean</a></dt><dt>4.1.13. <a href="#or-mapping-s1-11">subclass</a></dt><dt>4.1.14. <a href="#or-mapping-s1-11b">joined-subclass</a></dt><dt>4.1.15. <a href="#or-mapping-s1-12">map, set, list, bag</a></dt></dl></dd><dt>4.2. <a href="#or-mapping-s2">Hibernate Types</a></dt><dd><dl><dt>4.2.1. <a href="#or-mapping-s2-1">Entities and values</a></dt><dt>4.2.2. <a href="#or-mapping-s2-2">Basic value types</a></dt><dt>4.2.3. <a href="#or-mapping-s2-3">Persistent enum types</a></dt><dt>4.2.4. <a href="#or-mapping-s2-4">Custom value types</a></dt><dt>4.2.5. <a href="#or-mapping-s2-5">The object type</a></dt></dl></dd></dl></dd><dt>5. <a href="#adv-or-mapping">Advanced O/R Mapping</a></dt><dd><dl><dt>5.1. <a href="#adv-or-mapping-s1">Collections</a></dt><dd><dl><dt>5.1.1. <a href="#adv-or-mapping-s1-1">Persistent Collections</a></dt><dt>5.1.2. <a href="#adv-or-mapping-s1-3">Mapping a Collection</a></dt><dt>5.1.3. <a href="#adv-or-mapping-s1-5">Collections of Values and Many To Many Associations</a></dt><dt>5.1.4. <a href="#adv-or-mapping-s1-6">One To Many Associations</a></dt><dt>5.1.5. <a href="#adv-or-mapping-s1-7">Lazy Initialization</a></dt><dt>5.1.6. <a href="#adv-or-mapping-s1-8">Sorted Collections</a></dt><dt>5.1.7. <a href="#adv-or-mapping-s1-9">Garbage Collection</a></dt><dt>5.1.8. <a href="#adv-or-mapping-s1-10">Bidirectional Associations</a></dt><dt>5.1.9. <a href="#adv-or-mapping-s1-11">Ternary Associations</a></dt><dt>5.1.10. <a href="#adv-or-mapping-s1-12">Collection Example</a></dt></dl></dd><dt>5.2. <a href="#adv-or-mapping-s2">Components</a></dt><dd><dl><dt>5.2.1. <a href="#adv-or-mapping-s2-1">As Dependent Objects</a></dt><dt>5.2.2. <a href="#adv-or-mapping-s2-2">In Collections</a></dt><dt>5.2.3. <a href="#adv-or-mapping-s2-2b">As a Map Index</a></dt><dt>5.2.4. <a href="#adv-or-mapping-s2-3">As Composite Identifiers</a></dt><dt>5.2.5. <a href="#adv-or-mapping-s2-4">Dynabean components</a></dt></dl></dd><dt>5.3. <a href="#adv-or-mapping-s3">Cache</a></dt><dd><dl><dt>5.3.1. <a href="#adv-or-mapping-s3-1">Mapping</a></dt><dt>5.3.2. <a href="#adv-or-mapping-s3-2">Read Only Cache</a></dt><dt>5.3.3. <a href="#adv-or-mapping-s3-3">Read / Write Cache</a></dt></dl></dd><dt>5.4. <a href="#adv-or-mapping-s4">Proxies for Lazy Initialization</a></dt></dl></dd><dt>6. <a href="#manipulating-data">Manipulating Persistent Data</a></dt><dd><dl><dt>6.1. <a href="#manipulating-data-s1">Creating a persistent object</a></dt><dt>6.2. <a href="#manipulating-data-s2">Loading an object</a></dt><dt>6.3. <a href="#manipulating-data-s3">Querying</a></dt><dd><dl><dt>6.3.1. <a href="#manipulating-data-s4">Scalar queries</a></dt><dt>6.3.2. <a href="#manipulating-data-s5">The Query interface</a></dt><dt>6.3.3. <a href="#manipulating-data-s5b">Scrollable iteration</a></dt><dt>6.3.4. <a href="#manipulating-data-s6">Filtering collections</a></dt></dl></dd><dt>6.4. <a href="#manipulating-data-s7">Updating objects saved or loaded in the current session</a></dt><dt>6.5. <a href="#manipulating-data-s8">Updating objects saved or loaded in a previous session</a></dt><dt>6.6. <a href="#manipulating-data-s9">Deleting persistent objects</a></dt><dt>6.7. <a href="#manipulating-data-s10">Graphs of objects</a></dt><dd><dl><dt>6.7.1. <a href="#manipulating-data-s11a">Lifecycle objects</a></dt><dt>6.7.2. <a href="#manipulating-data-s11b">Persistence by Reachability</a></dt></dl></dd><dt>6.8. <a href="#manipulating-data-s12">Flushing</a></dt><dt>6.9. <a href="#manipulating-data-s13">Ending a Session</a></dt><dd><dl><dt>6.9.1. <a href="#manipulating-data-s13-1">Flushing the session</a></dt><dt>6.9.2. <a href="#manipulating-data-s13-2">Committing the transaction</a></dt><dt>6.9.3. <a href="#manipulating-data-s13-3">Closing the session</a></dt><dt>6.9.4. <a href="#manipulating-data-s13-4">Exception handling</a></dt></dl></dd><dt>6.10. <a href="#manipulating-data-s14">Interceptors</a></dt></dl></dd><dt>7. <a href="#query-language">Hibernate Query Language</a></dt><dd><dl><dt>7.1. <a href="#query-language-s1">Case Sensitivity</a></dt><dt>7.2. <a href="#query-language-s2">The from clause</a></dt><dt>7.3. <a href="#query-language-s3">Associations and joins</a></dt><dt>7.4. <a href="#query-language-s4">The select clause</a></dt><dt>7.5. <a href="#query-language-s4a">Aggregate functions</a></dt><dt>7.6. <a href="#query-language-s4b">polymorphism</a></dt><dt>7.7. <a href="#query-language-s5">The where clause</a></dt><dt>7.8. <a href="#query-language-s6">Expressions</a></dt><dt>7.9. <a href="#query-language-s7">The order by clause</a></dt><dt>7.10. <a href="#query-language-s8">The group by clause</a></dt><dt>7.11. <a href="#query-language-s9">Subqueries</a></dt></dl></dd><dt>8. <a href="#transactions">Transactions And Concurrency</a></dt><dd><dl><dt>8.1. <a href="#transactions-s1">Configurations, Sessions and Factories</a></dt><dt>8.2. <a href="#transactions-s2">Threads and connections</a></dt><dt>8.3. <a href="#transactions-s3">Optimistic Locking / Versioning</a></dt><dd><dl><dt>8.3.1. <a href="#transactions-s3-1">Long session with automatic versioning</a></dt><dt>8.3.2. <a href="#transactions-s3-2">Many sessions with automatic versioning</a></dt><dt>8.3.3. <a href="#transactions-s3-3">Application version checking</a></dt></dl></dd><dt>8.4. <a href="#transactions-s4">Session disconnection</a></dt><dt>8.5. <a href="#transactions-s5">Pessimistic Locking</a></dt></dl></dd><dt>9. <a href="#examples">Examples</a></dt><dd><dl><dt>9.1. <a href="#examples-s0">Employer/Employee</a></dt><dt>9.2. <a href="#examples-s1">Author/Work</a></dt><dt>9.3. <a href="#examples-s2">Customer/Order/Product</a></dt></dl></dd><dt>10. <a href="#best-practices">Best Practices</a></dt></dl></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="architecture"></a>Chapter 1. Architecture</h2></div></div><div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="architecture-s1"></a>1.1. Overview</h2></div></div><div></div></div><p> A (very) high-level view of the Hibernate architecture: </p><div class="mediaobject" align="center"><img src="../images/overview.gif" align="middle"></div><p> *************** *** 2611,2644 **** <tt class="literal">net.sf.hibernate.eg.FOO</tt> is not <tt class="literal">net.sf.hibernate.eg.Foo</tt> and ! <tt class="literal">foo.Bar</tt> is not ! <tt class="literal">foo.BAR</tt>. </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s2"></a>7.2. The from clause</h2></div></div><div></div></div><p> The simplest possible Hibernate query is of the form: ! </p><pre class="programlisting">from cat in class eg.Cat</pre><p> which simply returns all instances of the class <tt class="literal">eg.Cat</tt>. The query assigns the alias <tt class="literal">cat</tt> to <tt class="literal">Cat</tt> ! instances, so we could use that alias later in the query. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3"></a>7.3. The select clause</h2></div></div><div></div></div><p> ! A multipart <tt class="literal">from</tt> clause is possible. The <tt class="literal">select</tt> ! clause picks which classes to return in the result set. Consider: ! </p><pre class="programlisting">select mate from cat in class eg.Cat, mate in class eg.Cat ! where mate = cat.mate</pre><p> The query will select <tt class="literal">mate</tt>s of other <tt class="literal">Cat</tt>s. Actually, you may express this query more compactly as: ! </p><pre class="programlisting">select cat.mate from cat in class eg.Cat</pre><p>You may even select collection elements:</p><pre class="programlisting">select cat.kittens.elements from cat in class eg.Cat</pre><p> ! Queries may return properties any value type including properties of component type: ! </p><pre class="programlisting">select cat.name from cat in class eg.DomesticCat ! where cat.name like 'fri%'</pre><p> ! You may select multiple objects (Hibernate will return them in an array of type ! <tt class="literal">Object[]</tt>) ! </p><pre class="programlisting">select mother, offspr ! from mother in class eg.DomesticCat, offspr in class eg.Cat ! where offspr in mother.kittens.elements </pre><p> ! Queryies may even return aggregate functions of properties. Collections may also appear ! inside aggregate functions in the <tt class="literal">select</tt> clause. </p><pre class="programlisting">select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from cat in class eg.Cat ! select cat, count(cat.kittens.elements) from cat in class eg.Cat group by cat</pre><p> The supported aggregate functions are </p><div class="itemizedlist"><ul type="disc" compact><li><p> --- 2611,2689 ---- <tt class="literal">net.sf.hibernate.eg.FOO</tt> is not <tt class="literal">net.sf.hibernate.eg.Foo</tt> and ! <tt class="literal">foo.barSet</tt> is not ! <tt class="literal">foo.BARSET</tt>. </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s2"></a>7.2. The from clause</h2></div></div><div></div></div><p> The simplest possible Hibernate query is of the form: ! </p><pre class="programlisting">from eg.Cat as cat</pre><p> which simply returns all instances of the class <tt class="literal">eg.Cat</tt>. The query assigns the alias <tt class="literal">cat</tt> to <tt class="literal">Cat</tt> ! instances, so we could use that alias later in the query. The <tt class="literal">as</tt> ! keyword is optional; we could also write: ! </p><pre class="programlisting">from eg.Cat cat</pre><p> ! Multiple classes may appear, resulting in a cartesian product or "cross" join. ! </p><pre class="programlisting">from Formula as form, Parameter as param</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3"></a>7.3. Associations and joins</h2></div></div><div></div></div><p> ! We may also define aliases to associated entities using a <tt class="literal">join</tt>. ! </p><pre class="programlisting">from eg.Cat as cat ! inner join cat.mate as mate ! left outer join cat.kittens as kitten ! ! from eg.Cat as cat left join cat.mate.kittens as kittens ! ! from Formula form full join form.parameter param</pre><p> ! The supported join types are borrowed from ANSI SQL ! </p><div class="itemizedlist"><ul type="disc" compact><li><p> ! <tt class="literal">inner join</tt> ! </p></li><li><p> ! <tt class="literal">left outer join</tt> ! </p></li><li><p> ! <tt class="literal">right outer join</tt> (not recommended) ! </p></li><li><p> ! <tt class="literal">full join</tt> (not usually useful) ! </p></li></ul></div><p> ! The <tt class="literal">inner join</tt>, <tt class="literal">left outer join</tt> and ! <tt class="literal">right outer join</tt> constructs may be abbreviated. ! </p><pre class="programlisting">from eg.Cat as cat ! join cat.mate as mate ! left join cat.kittens as kitten</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4"></a>7.4. The select clause</h2></div></div><div></div></div><p> ! The <tt class="literal">select</tt> clause picks which objects and properties to return in ! the query result set. Consider: ! </p><pre class="programlisting">select mate ! from eg.Cat cat ! inner join cat.mate cat</pre><p> The query will select <tt class="literal">mate</tt>s of other <tt class="literal">Cat</tt>s. Actually, you may express this query more compactly as: ! </p><pre class="programlisting">select cat.mate from eg.Cat cat</pre><p> ! You may even select collection elements, using the special <tt class="literal">elements</tt> ! function. The following query returns all kittens of any cat. ! </p><pre class="programlisting">select elements(cat.kittens) from eg.Cat cat</pre><p> ! Queries may return properties of any value type including properties of component type: ! </p><pre class="programlisting">select cat.name from eg.DomesticCat cat ! where cat.name like 'fri%' ! ! select cust.name.firstName from Customer as cust</pre><p> ! Queries may return multiple objects and/or properties as an array of type ! <tt class="literal">Object[]</tt> ! </p><pre class="programlisting">select cat, offspr, mate.name ! from eg.DomesticCat as mother ! inner join mother.mate as mate ! left outer join mother.kittens as offspr</pre><p> ! or as an actual typesafe Java object ! </p><pre class="programlisting">select new Family(cat, mate, offspr) ! from eg.DomesticCat as mother ! join mother.mate as mate ! left join mother.kittens as offspr</pre><p> ! assuming that the class <tt class="literal">Family</tt> has an appropriate constructor. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4a"></a>7.5. Aggregate functions</h2></div></div><div></div></div><p> ! Queryies may even return aggregate functions of properties. </p><pre class="programlisting">select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from eg.Cat cat></programlisting> ! <para> ! Collections may also appear inside aggregate functions in the <literal>select</literal> ! clause. ! </para> ! ! <programlisting><![CDATA[select cat, count( elements(cat.kittens) ) ! from eg.Cat cat group by cat</pre><p> The supported aggregate functions are </p><div class="itemizedlist"><ul type="disc" compact><li><p> *************** *** 2651,2682 **** The <tt class="literal">distinct</tt> and <tt class="literal">all</tt> keywords may be used and have the same semantics as in SQL. ! </p><pre class="programlisting">select distinct cat.name from cat in class eg.Cat</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3b"></a>7.4. polymorphism</h2></div></div><div></div></div><p> A query like: ! </p><pre class="programlisting">from cat in class eg.Cat</pre><p> returns instances not only of <tt class="literal">Cat</tt>, but also of subclasses like ! <tt class="literal">DomesticCat</tt>. Hibernate queries may name <span class="emphasis"><em>any</em></span> ! Java class or interface in the <tt class="literal">from</tt> clause. The query will ! return instances of all persistent classes that extend that class or implement ! the interface. The following query would return all persistent objects: ! </p><pre class="programlisting">from o in class java.lang.Object</pre><p> The interface <tt class="literal">Named</tt> might be implemented by various persistent classes: ! </p><pre class="programlisting">from n in class eg.Named, m in class eg.Named where n.name = m.name</pre><p> Note that these last two queries will require more than one SQL <tt class="literal">SELECT</tt>. This means that the <tt class="literal">order by</tt> clause does not correctly order the whole result set. (It also means you can't call these queries using <tt class="literal">Query.scroll()</tt>.) ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4"></a>7.5. from collections</h2></div></div><div></div></div><p> ! You can select entities (but not values) from a collection ! </p><pre class="programlisting">select kitten from ! cat in class eg.Cat, ! kitten in cat.kittens.elements</pre><p> ! The <tt class="literal">elements</tt> construct is like a special property referring to the ! element set of the collection. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s5"></a>7.6. The where clause</h2></div></div><div></div></div><p> ! The <tt class="literal">where</tt> clause allows you to narrow the list ! of instances returned. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.name='Fritz'</pre><p> returns instances of <tt class="literal">Cat</tt> named 'Fritz'. ! </p><pre class="programlisting">select foo from foo in class eg.Foo, bar in class eg.Bar where foo.startDate = bar.date</pre><p> will return all instances of <tt class="literal">Foo</tt> for which --- 2696,2721 ---- The <tt class="literal">distinct</tt> and <tt class="literal">all</tt> keywords may be used and have the same semantics as in SQL. ! </p><pre class="programlisting">select distinct cat.name from eg.Cat cat ! ! select count(distinct cat.name), count(cat) from eg.Cat cat</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4b"></a>7.6. polymorphism</h2></div></div><div></div></div><p> A query like: ! </p><pre class="programlisting">from eg.Cat as cat</pre><p> returns instances not only of <tt class="literal">Cat</tt>, but also of subclasses like ! <tt class="literal">DomesticCat</tt>. Hibernate queries may name <span class="emphasis"><em>any</em></span> Java ! class or interface in the <tt class="literal">from</tt> clause. The query will return instances ! of all persistent classes that extend that class or implement the interface. The following ! query would return all persistent objects: ! </p><pre class="programlisting">from java.lang.Object o</pre><p> The interface <tt class="literal">Named</tt> might be implemented by various persistent classes: ! </p><pre class="programlisting">from eg.Named n, eg.Named m where n.name = m.name</pre><p> Note that these last two queries will require more than one SQL <tt class="literal">SELECT</tt>. This means that the <tt class="literal">order by</tt> clause does not correctly order the whole result set. (It also means you can't call these queries using <tt class="literal">Query.scroll()</tt>.) ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s5"></a>7.7. The where clause</h2></div></div><div></div></div><p> ! The <tt class="literal">where</tt> clause allows you to narrow the list of instances returned. ! </p><pre class="programlisting">from eg.Cat as cat where cat.name='Fritz'</pre><p> returns instances of <tt class="literal">Cat</tt> named 'Fritz'. ! </p><pre class="programlisting">select foo from eg.Foo foo, eg.Bar bar where foo.startDate = bar.date</pre><p> will return all instances of <tt class="literal">Foo</tt> for which *************** *** 2686,2693 **** <tt class="literal">Foo</tt>. Compound path expressions make the <tt class="literal">where</tt> clause extremely powerful. Consider: ! </p><pre class="programlisting">from cat in class eg.Cat where cat.mate.name is not null</pre><p> ! This query translates to an SQL query with a table join. If you were to write something like ! </p><pre class="programlisting">from foo in class eg.Foo where foo.bar.baz.customer.address.city is not null</pre><p> you would end up with a query that would require four table joins in SQL. --- 2725,2732 ---- <tt class="literal">Foo</tt>. Compound path expressions make the <tt class="literal">where</tt> clause extremely powerful. Consider: ! </p><pre class="programlisting">from eg.Cat cat where cat.mate.name is not null</pre><p> ! This query translates to an SQL query with a table (inner) join. If you were to write something like ! </p><pre class="programlisting">from eg.Foo foo where foo.bar.baz.customer.address.city is not null</pre><p> you would end up with a query that would require four table joins in SQL. *************** *** 2695,2707 **** The <tt class="literal">=</tt> operator may be used to compare not only properties, but also instances: ! </p><pre class="programlisting">from cat in class eg.Cat, rival in class eg.Cat where cat.mate = rival.mate ! select cat, mate from cat in class eg.Cat, mate in class eg.Cat where cat.mate = mate</pre><p> The special property (lowercase) <tt class="literal">id</tt> may be used to reference the unique identifier of an object. (You may also use its property name.) ! </p><pre class="programlisting">from cat in class eg.Cat where cat.id = 123 ! from cat in class eg.Cat where cat.mate.id = 69</pre><p> The second query is efficient. No table join is required! </p><p> --- 2734,2746 ---- The <tt class="literal">=</tt> operator may be used to compare not only properties, but also instances: ! </p><pre class="programlisting">from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate ! select cat, mate from eg.Cat cat, eg.Cat mate where cat.mate = mate</pre><p> The special property (lowercase) <tt class="literal">id</tt> may be used to reference the unique identifier of an object. (You may also use its property name.) ! </p><pre class="programlisting">from eg.Cat as cat where cat.id = 123 ! from eg.Cat as cat where cat.mate.id = 69</pre><p> The second query is efficient. No table join is required! </p><p> *************** *** 2709,2716 **** has a composite identifier consisting of <tt class="literal">country</tt> and <tt class="literal">medicareNumber</tt>. ! </p><pre class="programlisting">from person in class bank.Person where person.id.country = 'AU' and person.id.medicareNumber = 123456 ! from account in class bank.Account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> Once again, the second query requires no table join. --- 2748,2755 ---- has a composite identifier consisting of <tt class="literal">country</tt> and <tt class="literal">medicareNumber</tt>. ! </p><pre class="programlisting">from bank.Person person where person.id.country = 'AU' and person.id.medicareNumber = 123456 ! from bank.Account account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> Once again, the second query requires no table join. *************** *** 2719,2723 **** of an instance in the case of polymorphic persistence. A Java class name embedded in the where clause will be translated to its discriminator value. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.class = eg.DomesticCat</pre><p> You may also specify properties of components (and of components of components). Never try to use a path-expression that ends in a property of component type --- 2758,2762 ---- of an instance in the case of polymorphic persistence. A Java class name embedded in the where clause will be translated to its discriminator value. ! </p><pre class="programlisting">from eg.Cat cat where cat.class = eg.DomesticCat</pre><p> You may also specify properties of components (and of components of components). Never try to use a path-expression that ends in a property of component type *************** *** 2725,2729 **** is an entity with a component <tt class="literal">address</tt> </p><pre class="programlisting">store.owner.address.city //okay ! store.owner.address //error!</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s6"></a>7.7. Expressions</h2></div></div><div></div></div><p> Expressions allowed in the <tt class="literal">where</tt> clause include most of the kind of things you could write in SQL: --- 2764,2768 ---- is an entity with a component <tt class="literal">address</tt> </p><pre class="programlisting">store.owner.address.city //okay ! store.owner.address //error!</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s6"></a>7.8. Expressions</h2></div></div><div></div></div><p> Expressions allowed in the <tt class="literal">where</tt> clause include most of the kind of things you could write in SQL: *************** *** 2755,2791 **** </p></li></ul></div><p> <tt class="literal">in</tt> and <tt class="literal">between</tt> may be used as follows: ! </p><pre class="programlisting">from cat in class eg.DomesticCat where cat.name between 'A' and 'B' ! from cat in class eg.DomesticCat where cat.name in ( 'Foo', 'Bar', Baz" )</pre><p> and the negated forms may be written ! </p><pre class="programlisting">from cat in class eg.DomesticCat where cat.name not between 'A' and 'B' ! from cat in class eg.DomesticCat where cat.name not in ( 'Foo', 'Bar', Baz" )</pre><p> Likewise, <tt class="literal">is null</tt> and <tt class="literal">is not null</tt> may be used to test for null values. </p><p> ! You may test the size of a collection with the special property <tt class="literal">size</tt> ! </p><pre class="programlisting">from cat in class eg.Cat where cat.kittens.size > 0</pre><p> For indexed collections, you may refer to the minimum and maximum indices using <tt class="literal">minIndex</tt> and <tt class="literal">maxIndex</tt>. Similarly, you may refer to the minimum and maximum elements of a collection of basic type using <tt class="literal">minElement</tt> and <tt class="literal">maxElement</tt>. ! </p><pre class="programlisting">from cal in class Calendar where cal.holidays.maxElement > current date</pre><p> ! The SQL functions <tt class="literal">any, some, all, exists, in</tt> are supported when passed one of ! two special properties of a collection. The special properties are <tt class="literal">elements</tt> and ! <tt class="literal">indices</tt>. Respectively they represent the element set and the index set of the ! collection. ! </p><pre class="programlisting">select mother from mother in class eg.Cat, kit in class eg.Cat ! where kit in foo.kittens.elements ! select p from list in class eg.NameList, p in class eg.Person ! where p.name = some list.names.elements ! from cat in class eg.Cat where exists cat.kittens.elements ! from p in class eg.Player where 3 > all p.scores.elements ! from show in class eg.Show ! where 'fizard' in show.acts.indices</pre><p> Note that these constructs - <tt class="literal">size</tt>, <tt class="literal">elements</tt>, <tt class="literal">indices</tt>, <tt class="literal">minIndex</tt>, <tt class="literal">maxIndex</tt>, --- 2794,2835 ---- </p></li></ul></div><p> <tt class="literal">in</tt> and <tt class="literal">between</tt> may be used as follows: ! </p><pre class="programlisting">from eg.DomesticCat cat where cat.name between 'A' and 'B' ! from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', Baz" )</pre><p> and the negated forms may be written ! </p><pre class="programlisting">from eg.DomesticCat cat where cat.name not between 'A' and 'B' ! from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', Baz" )</pre><p> Likewise, <tt class="literal">is null</tt> and <tt class="literal">is not null</tt> may be used to test for null values. </p><p> ! You may test the size of a collection with the special property <tt class="literal">size</tt>, or ! the special <tt class="literal">size()</tt> function. ! </p><pre class="programlisting">from eg.Cat cat where cat.kittens.size > 0 ! ! from eg.Cat cat where size(cat.kittens) > 0</pre><p> For indexed collections, you may refer to the minimum and maximum indices using <tt class="literal">minIndex</tt> and <tt class="literal">maxIndex</tt>. Similarly, you may refer to the minimum and maximum elements of a collection of basic type using <tt class="literal">minElement</tt> and <tt class="literal">maxElement</tt>. ! </p><pre class="programlisting">from Calendar cal where cal.holidays.maxElement > current date</pre><p> ! There are also functional forms (which, unlike the constructs above, are not case sensitive): ! </p><pre class="programlisting">from Order order where maxindex(order.items) > 100 ! from Order order where minelement(order.items) > 10000</pre><p> ! The SQL functions <tt class="literal">any, some, all, exists, in</tt> are supported when passed the element ! or index set of a collection (<tt class="literal">elements</tt> and <tt class="literal">indices</tt> functions) ! or the result of a subquery (see below). ! </p><pre class="programlisting">select mother from eg.Cat as mother, eg.Cat as kit ! where kit in elements(foo.kittens) ! select p from eg.NameList list, eg.Person p ! where p.name = some elements(list.names) ! from eg.Cat cat where exists elements(cat.kittens) ! from eg.Player p where 3 > all elements(p.scores) ! ! from eg.Show show where 'fizard' in indices(show.acts)</pre><p> Note that these constructs - <tt class="literal">size</tt>, <tt class="literal">elements</tt>, <tt class="literal">indices</tt>, <tt class="literal">minIndex</tt>, <tt class="literal">maxIndex</tt>, *************** *** 2795,2829 **** in a <tt class="literal">where</tt> clause: only for databases with subselects </p></li><li><p> - in a <tt class="literal">from</tt> clause: only <tt class="literal">elements</tt> makes sense ... and - only for a collection of entities - </p></li><li><p> in a <tt class="literal">select</tt> clause: only <tt class="literal">elements</tt> and <tt class="literal">indices</tt> make sense </p></li></ul></div><p> Elements of indexed collections (arrays, lists, maps) may be referred to by index (in a where clause only) ! </p><pre class="programlisting">from order in class Order where order.items[0].id = 1234 ! select person from person in class Person, calendar in class Calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar ! select item from item in class Item, order in class Order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 ! select item from item in class Item, order in class Order ! where order.items[order.items.maxIndex] = item and order.id = 11</pre><p> The expression inside <tt class="literal">[]</tt> may even be an arithmetic expression. ! </p><p> Scalar SQL functions supported by the underlying database may be used ! </p><pre class="programlisting">from cat in class eg.DomesticCat where upper(cat.name) like 'FRI%'</pre><p> If you are not yet convinced by all this, think how much longer and less readable the following query would be in SQL: </p><pre class="programlisting">select cust ! from prod in class Product, ! store in class Store, ! cust in store.customers where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) ! and prod = all cust.currentOrder.lineItems.elements</pre><p> <span class="emphasis"><em>Hint:</em></span> something like </p><pre class="programlisting">SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order --- 2839,2871 ---- in a <tt class="literal">where</tt> clause: only for databases with subselects </p></li><li><p> in a <tt class="literal">select</tt> clause: only <tt class="literal">elements</tt> and <tt class="literal">indices</tt> make sense </p></li></ul></div><p> Elements of indexed collections (arrays, lists, maps) may be referred to by index (in a where clause only) ! </p><pre class="programlisting">from Order order where order.items[0].id = 1234 ! select person from Person person, Calendar calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar ! select item from Item item, Order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 ! select item from Item item, Order order ! where order.items[ maxindex(order.items) ] = item and order.id = 11</pre><p> The expression inside <tt class="literal">[]</tt> may even be an arithmetic expression. ! </p><pre class="programlisting">select item from Item item, Order order ! where order.items[ size(order.items) - 1 ] = item</pre><p> Scalar SQL functions supported by the underlying database may be used ! </p><pre class="programlisting">from eg.DomesticCat cat where upper(cat.name) like 'FRI%'</pre><p> If you are not yet convinced by all this, think how much longer and less readable the following query would be in SQL: </p><pre class="programlisting">select cust ! from Product prod, ! Store store ! inner join store.customers cust where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) ! and prod = all elements(cust.currentOrder.lineItems)</pre><p> <span class="emphasis"><em>Hint:</em></span> something like </p><pre class="programlisting">SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order *************** *** 2843,2871 **** WHERE item.order_id = o.id AND cust.current_order = o.id ! )</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s7"></a>7.8. The order by clause</h2></div></div><div></div></div><p> The list returned by a query may be ordered by any property of a returned class or components: ! </p><pre class="programlisting">from cat in class eg.DomesticCat order by cat.name asc, cat.weight desc, cat.birthdate</pre><p> The optional <tt class="literal">asc</tt> or <tt class="literal">desc</tt> indicate ascending or descending order respectively. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s8"></a>7.9. The group by clause</h2></div></div><div></div></div><p> A query that returns aggregate values may be grouped by any property of a returned class or components: ! </p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from cat in class eg.Cat group by cat.color ! select foo.id, avg(foo.names.elements), max(foo.names.indices) from foo in class eg.Foo group by foo.id</pre><p>Note: You may use the <tt class="literal">elements</tt> and <tt class="literal">indices</tt> constructs ! inside a select clause, even on databases with no subselects.</p><p>A <tt class="literal">having</tt> clause is also allowed.</p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from foo in class eg.Foo ! group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s9"></a>7.10. Subqueries</h2></div></div><div></div></div><p> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). eg. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.weight > ! ( select avg(cat.weight) from cat in class eg.DomesticCat ) ! from cat in class eg.DomesticCat where cat.name = ! some( select list.name from list in class eg.NameList ) ! from cat in class eg.Cat where not exists ! ( from mate in class eg.Cat where mate.mate = cat )</pre></div></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="transactions"></a>Chapter 8. Transactions And Concurrency</h2></div></div><div></div></div><p> Hibernate is not itself a database. It is a lightweight object-relational mapping tool. Transaction management is delegated to the underlying database --- 2885,2914 ---- WHERE item.order_id = o.id AND cust.current_order = o.id ! )</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s7"></a>7.9. The order by clause</h2></div></div><div></div></div><p> The list returned by a query may be ordered by any property of a returned class or components: ! </p><pre class="programlisting">from eg.DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate</pre><p> The optional <tt class="literal">asc</tt> or <tt class="literal">desc</tt> indicate ascending or descending order respectively. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s8"></a>7.10. The group by clause</h2></div></div><div></div></div><p> A query that returns aggregate values may be grouped by any property of a returned class or components: ! </p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from eg.Cat cat group by cat.color ! select foo.id, avg( elements(foo.names) ), max( indices(foo.names) ) from eg.Foo foo group by foo.id</pre><p>Note: You may use the <tt class="literal">elements</tt> and <tt class="literal">indices</tt> constructs ! inside a select clause, even on databases with no subselects.</p><p>A <tt class="literal">having</tt> clause is also allowed.</p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from eg.Cat cat ! group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s9"></a>7.11. Subqueries</h2></div></div><div></div></div><p> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). Even /correlated/ subqueries ! (subqueries that refer to an alias in the outer query) are allowed. ! </p><pre class="programlisting">from eg.Cat fatcat where fatcat.weight > ! ( select avg(cat.weight) from eg.DomesticCat cat ) ! from eg.DomesticCat cat where cat.name = ! some( select list.name from eg.NameList list ) ! from eg.Cat cat where not exists ! ( from eg.Cat mate where mate.mate = cat )</pre></div></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="transactions"></a>Chapter 8. Transactions And Concurrency</h2></div></div><div></div></div><p> Hibernate is not itself a database. It is a lightweight object-relational mapping tool. Transaction management is delegated to the underlying database |
From: <tu...@us...> - 2003-03-02 13:59:05
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/html In directory sc8-pr-cvs1:/tmp/cvs-serv23405/doc/reference/html Modified Files: index.html query-language.html Log Message: Version Update for Release Index: index.html =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/html/index.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** index.html 23 Feb 2003 13:45:25 -0000 1.3 --- index.html 2 Mar 2003 13:59:02 -0000 1.4 *************** *** 1,3 **** <html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> ! <title>HIBERNATE - Relational Persistence for Idiomatic Java</title><link rel="stylesheet" href="../style.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.60.1"><link rel="home" href="index.html" title="HIBERNATE - Relational Persistence for Idiomatic Java"><link rel="next" href="architecture.html" title="Chapter 1. Architecture"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">HIBERNATE - Relational Persistence for Idiomatic Java</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="architecture.html">Next</a></td></tr></table><hr></div><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e1"></a>HIBERNATE - Relational Persistence for Idiomatic Java</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><p class="releaseinfo">2.0 beta2</p></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="architecture.html">Architecture</a></dt><dd><dl><dt>1.1. <a href="architecture.html#architecture-s1">Overview</a></dt><dt>1.2. <a href="architecture.html#architecture-s2">Persistent Object Identity</a></dt><dt>1.3. <a href="architecture.html#architecture-s3">JMX Integration</a></dt></dl></dd><dt>2. <a href="session-configuration.html">SessionFactory Configuration</a></dt><dd><dl><dt>2.1. <a href="session-configuration.html#session-configuration-s1">Programmatic Configuration</a></dt><dt>2.2. <a href="session-configuration.html#session-configuration-s2">Obtaining a SessionFactory</a></dt><dt>2.3. <a href="session-configuration.html#session-configuration-s3">User provided JDBC connection</a></dt><dt>2.4. <a href="session-configuration.html#session-configuration-s4">Hibernate provided JDBC connection</a></dt><dt>2.5. <a href="session-configuration.html#session-configuration-s5">Other properties</a></dt><dt>2.6. <a href="session-configuration.html#session-configuration-s6">XML Configuration File</a></dt><dt>2.7. <a href="session-configuration.html#session-configuration-s7">Logging</a></dt></dl></dd><dt>3. <a href="persistent-classes.html">Persistent Classes</a></dt><dd><dl><dt>3.1. <a href="persistent-classes.html#persistent-classes-s1">Simple Example</a></dt><dd><dl><dt>3.1.1. <a href="persistent-classes.html#persistent-classes-s1-1">Declare accessors and mutators for persistent fields</a></dt><dt>3.1.2. <a href="persistent-classes.html#persistent-classes-s1-2">Implement a default constructor</a></dt><dt>3.1.3. <a href="persistent-classes.html#persistent-classes-s1-3">Provide an identifier property (optional)</a></dt></dl></dd><dt>3.2. <a href="persistent-classes.html#persistent-classes-s2">Inheritance</a></dt><dt>3.3. <a href="persistent-classes.html#persistent-classes-s3">Persistent Lifecycle Callbacks</a></dt><dt>3.4. <a href="persistent-classes.html#persistent-classes-s4">Validatable</a></dt></dl></dd><dt>4. <a href="or-mapping.html">Basic O/R Mapping</a></dt><dd><dl><dt>4.1. <a href="or-mapping.html#or-mapping-s1">Mapping declaration</a></dt><dd><dl><dt>4.1.1. <a href="or-mapping.html#or-mapping-s1-1">Doctype</a></dt><dt>4.1.2. <a href="or-mapping.html#or-mapping-s1-2">hibernate-mapping</a></dt><dt>4.1.3. <a href="or-mapping.html#or-mapping-s1-3">class</a></dt><dt>4.1.4. <a href="or-mapping.html#or-mapping-s1-4">id</a></dt><dt>4.1.5. <a href="or-mapping.html#or-mapping-s1-4b">composite-id</a></dt><dt>4.1.6. <a href="or-mapping.html#or-mapping-s1-5">discriminator</a></dt><dt>4.1.7. <a href="or-mapping.html#or-mapping-s1-6">version (optional)</a></dt><dt>4.1.8. <a href="or-mapping.html#or-mapping-s1-6b">timestamp (optional)</a></dt><dt>4.1.9. <a href="or-mapping.html#or-mapping-s1-7">property</a></dt><dt>4.1.10. <a href="or-mapping.html#or-mapping-s1-8">many-to-one</a></dt><dt>4.1.11. <a href="or-mapping.html#or-mapping-s1-9">one-to-one</a></dt><dt>4.1.12. <a href="or-mapping.html#or-mapping-s1-10">component, dynabean</a></dt><dt>4.1.13. <a href="or-mapping.html#or-mapping-s1-11">subclass</a></dt><dt>4.1.14. <a href="or-mapping.html#or-mapping-s1-11b">joined-subclass</a></dt><dt>4.1.15. <a href="or-mapping.html#or-mapping-s1-12">map, set, list, bag</a></dt></dl></dd><dt>4.2. <a href="or-mapping.html#or-mapping-s2">Hibernate Types</a></dt><dd><dl><dt>4.2.1. <a href="or-mapping.html#or-mapping-s2-1">Entities and values</a></dt><dt>4.2.2. <a href="or-mapping.html#or-mapping-s2-2">Basic value types</a></dt><dt>4.2.3. <a href="or-mapping.html#or-mapping-s2-3">Persistent enum types</a></dt><dt>4.2.4. <a href="or-mapping.html#or-mapping-s2-4">Custom value types</a></dt><dt>4.2.5. <a href="or-mapping.html#or-mapping-s2-5">The object type</a></dt></dl></dd></dl></dd><dt>5. <a href="adv-or-mapping.html">Advanced O/R Mapping</a></dt><dd><dl><dt>5.1. <a href="adv-or-mapping.html#adv-or-mapping-s1">Collections</a></dt><dd><dl><dt>5.1.1. <a href="adv-or-mapping.html#adv-or-mapping-s1-1">Persistent Collections</a></dt><dt>5.1.2. <a href="adv-or-mapping.html#adv-or-mapping-s1-3">Mapping a Collection</a></dt><dt>5.1.3. <a href="adv-or-mapping.html#adv-or-mapping-s1-5">Collections of Values and Many To Many Associations</a></dt><dt>5.1.4. <a href="adv-or-mapping.html#adv-or-mapping-s1-6">One To Many Associations</a></dt><dt>5.1.5. <a href="adv-or-mapping.html#adv-or-mapping-s1-7">Lazy Initialization</a></dt><dt>5.1.6. <a href="adv-or-mapping.html#adv-or-mapping-s1-8">Sorted Collections</a></dt><dt>5.1.7. <a href="adv-or-mapping.html#adv-or-mapping-s1-9">Garbage Collection</a></dt><dt>5.1.8. <a href="adv-or-mapping.html#adv-or-mapping-s1-10">Bidirectional Associations</a></dt><dt>5.1.9. <a href="adv-or-mapping.html#adv-or-mapping-s1-11">Ternary Associations</a></dt><dt>5.1.10. <a href="adv-or-mapping.html#adv-or-mapping-s1-12">Collection Example</a></dt></dl></dd><dt>5.2. <a href="adv-or-mapping.html#adv-or-mapping-s2">Components</a></dt><dd><dl><dt>5.2.1. <a href="adv-or-mapping.html#adv-or-mapping-s2-1">As Dependent Objects</a></dt><dt>5.2.2. <a href="adv-or-mapping.html#adv-or-mapping-s2-2">In Collections</a></dt><dt>5.2.3. <a href="adv-or-mapping.html#adv-or-mapping-s2-2b">As a Map Index</a></dt><dt>5.2.4. <a href="adv-or-mapping.html#adv-or-mapping-s2-3">As Composite Identifiers</a></dt><dt>5.2.5. <a href="adv-or-mapping.html#adv-or-mapping-s2-4">Dynabean components</a></dt></dl></dd><dt>5.3. <a href="adv-or-mapping.html#adv-or-mapping-s3">Cache</a></dt><dd><dl><dt>5.3.1. <a href="adv-or-mapping.html#adv-or-mapping-s3-1">Mapping</a></dt><dt>5.3.2. <a href="adv-or-mapping.html#adv-or-mapping-s3-2">Read Only Cache</a></dt><dt>5.3.3. <a href="adv-or-mapping.html#adv-or-mapping-s3-3">Read / Write Cache</a></dt></dl></dd><dt>5.4. <a href="adv-or-mapping.html#adv-or-mapping-s4">Proxies for Lazy Initialization</a></dt></dl></dd><dt>6. <a href="manipulating-data.html">Manipulating Persistent Data</a></dt><dd><dl><dt>6.1. <a href="manipulating-data.html#manipulating-data-s1">Creating a persistent object</a></dt><dt>6.2. <a href="manipulating-data.html#manipulating-data-s2">Loading an object</a></dt><dt>6.3. <a href="manipulating-data.html#manipulating-data-s3">Querying</a></dt><dd><dl><dt>6.3.1. <a href="manipulating-data.html#manipulating-data-s4">Scalar queries</a></dt><dt>6.3.2. <a href="manipulating-data.html#manipulating-data-s5">The Query interface</a></dt><dt>6.3.3. <a href="manipulating-data.html#manipulating-data-s5b">Scrollable iteration</a></dt><dt>6.3.4. <a href="manipulating-data.html#manipulating-data-s6">Filtering collections</a></dt></dl></dd><dt>6.4. <a href="manipulating-data.html#manipulating-data-s7">Updating objects saved or loaded in the current session</a></dt><dt>6.5. <a href="manipulating-data.html#manipulating-data-s8">Updating objects saved or loaded in a previous session</a></dt><dt>6.6. <a href="manipulating-data.html#manipulating-data-s9">Deleting persistent objects</a></dt><dt>6.7. <a href="manipulating-data.html#manipulating-data-s10">Graphs of objects</a></dt><dd><dl><dt>6.7.1. <a href="manipulating-data.html#manipulating-data-s11a">Lifecycle objects</a></dt><dt>6.7.2. <a href="manipulating-data.html#manipulating-data-s11b">Persistence by Reachability</a></dt></dl></dd><dt>6.8. <a href="manipulating-data.html#manipulating-data-s12">Flushing</a></dt><dt>6.9. <a href="manipulating-data.html#manipulating-data-s13">Ending a Session</a></dt><dd><dl><dt>6.9.1. <a href="manipulating-data.html#manipulating-data-s13-1">Flushing the session</a></dt><dt>6.9.2. <a href="manipulating-data.html#manipulating-data-s13-2">Committing the transaction</a></dt><dt>6.9.3. <a href="manipulating-data.html#manipulating-data-s13-3">Closing the session</a></dt><dt>6.9.4. <a href="manipulating-data.html#manipulating-data-s13-4">Exception handling</a></dt></dl></dd><dt>6.10. <a href="manipulating-data.html#manipulating-data-s14">Interceptors</a></dt></dl></dd><dt>7. <a href="query-language.html">Hibernate Query Language</a></dt><dd><dl><dt>7.1. <a href="query-language.html#query-language-s1">Case Sensitivity</a></dt><dt>7.2. <a href="query-language.html#query-language-s2">The from clause</a></dt><dt>7.3. <a href="query-language.html#query-language-s3">The select clause</a></dt><dt>7.4. <a href="query-language.html#query-language-s3b">polymorphism</a></dt><dt>7.5. <a href="query-language.html#query-language-s4">from collections</a></dt><dt>7.6. <a href="query-language.html#query-language-s5">The where clause</a></dt><dt>7.7. <a href="query-language.html#query-language-s6">Expressions</a></dt><dt>7.8. <a href="query-language.html#query-language-s7">The order by clause</a></dt><dt>7.9. <a href="query-language.html#query-language-s8">The group by clause</a></dt><dt>7.10. <a href="query-language.html#query-language-s9">Subqueries</a></dt></dl></dd><dt>8. <a href="transactions.html">Transactions And Concurrency</a></dt><dd><dl><dt>8.1. <a href="transactions.html#transactions-s1">Configurations, Sessions and Factories</a></dt><dt>8.2. <a href="transactions.html#transactions-s2">Threads and connections</a></dt><dt>8.3. <a href="transactions.html#transactions-s3">Optimistic Locking / Versioning</a></dt><dd><dl><dt>8.3.1. <a href="transactions.html#transactions-s3-1">Long session with automatic versioning</a></dt><dt>8.3.2. <a href="transactions.html#transactions-s3-2">Many sessions with automatic versioning</a></dt><dt>8.3.3. <a href="transactions.html#transactions-s3-3">Application version checking</a></dt></dl></dd><dt>8.4. <a href="transactions.html#transactions-s4">Session disconnection</a></dt><dt>8.5. <a href="transactions.html#transactions-s5">Pessimistic Locking</a></dt></dl></dd><dt>9. <a href="examples.html">Examples</a></dt><dd><dl><dt>9.1. <a href="examples.html#examples-s0">Employer/Employee</a></dt><dt>9.2. <a href="examples.html#examples-s1">Author/Work</a></dt><dt>9.3. <a href="examples.html#examples-s2">Customer/Order/Product</a></dt></dl></dd><dt>10. <a href="best-practices.html">Best Practices</a></dt></dl></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="architecture.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> Chapter 1. Architecture</td></tr></table></div></body></html> \ No newline at end of file --- 1,3 ---- <html><head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> ! <title>HIBERNATE - Relational Persistence for Idiomatic Java</title><link rel="stylesheet" href="../style.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.60.1"><link rel="home" href="index.html" title="HIBERNATE - Relational Persistence for Idiomatic Java"><link rel="next" href="architecture.html" title="Chapter 1. Architecture"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">HIBERNATE - Relational Persistence for Idiomatic Java</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="architecture.html">Next</a></td></tr></table><hr></div><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="d0e1"></a>HIBERNATE - Relational Persistence for Idiomatic Java</h1></div><div><h2 class="subtitle">Reference Documentation</h2></div><div><p class="releaseinfo">2.0 beta4</p></div></div><div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>1. <a href="architecture.html">Architecture</a></dt><dd><dl><dt>1.1. <a href="architecture.html#architecture-s1">Overview</a></dt><dt>1.2. <a href="architecture.html#architecture-s2">Persistent Object Identity</a></dt><dt>1.3. <a href="architecture.html#architecture-s3">JMX Integration</a></dt></dl></dd><dt>2. <a href="session-configuration.html">SessionFactory Configuration</a></dt><dd><dl><dt>2.1. <a href="session-configuration.html#session-configuration-s1">Programmatic Configuration</a></dt><dt>2.2. <a href="session-configuration.html#session-configuration-s2">Obtaining a SessionFactory</a></dt><dt>2.3. <a href="session-configuration.html#session-configuration-s3">User provided JDBC connection</a></dt><dt>2.4. <a href="session-configuration.html#session-configuration-s4">Hibernate provided JDBC connection</a></dt><dt>2.5. <a href="session-configuration.html#session-configuration-s5">Other properties</a></dt><dt>2.6. <a href="session-configuration.html#session-configuration-s6">XML Configuration File</a></dt><dt>2.7. <a href="session-configuration.html#session-configuration-s7">Logging</a></dt></dl></dd><dt>3. <a href="persistent-classes.html">Persistent Classes</a></dt><dd><dl><dt>3.1. <a href="persistent-classes.html#persistent-classes-s1">Simple Example</a></dt><dd><dl><dt>3.1.1. <a href="persistent-classes.html#persistent-classes-s1-1">Declare accessors and mutators for persistent fields</a></dt><dt>3.1.2. <a href="persistent-classes.html#persistent-classes-s1-2">Implement a default constructor</a></dt><dt>3.1.3. <a href="persistent-classes.html#persistent-classes-s1-3">Provide an identifier property (optional)</a></dt></dl></dd><dt>3.2. <a href="persistent-classes.html#persistent-classes-s2">Inheritance</a></dt><dt>3.3. <a href="persistent-classes.html#persistent-classes-s3">Persistent Lifecycle Callbacks</a></dt><dt>3.4. <a href="persistent-classes.html#persistent-classes-s4">Validatable</a></dt></dl></dd><dt>4. <a href="or-mapping.html">Basic O/R Mapping</a></dt><dd><dl><dt>4.1. <a href="or-mapping.html#or-mapping-s1">Mapping declaration</a></dt><dd><dl><dt>4.1.1. <a href="or-mapping.html#or-mapping-s1-1">Doctype</a></dt><dt>4.1.2. <a href="or-mapping.html#or-mapping-s1-2">hibernate-mapping</a></dt><dt>4.1.3. <a href="or-mapping.html#or-mapping-s1-3">class</a></dt><dt>4.1.4. <a href="or-mapping.html#or-mapping-s1-4">id</a></dt><dt>4.1.5. <a href="or-mapping.html#or-mapping-s1-4b">composite-id</a></dt><dt>4.1.6. <a href="or-mapping.html#or-mapping-s1-5">discriminator</a></dt><dt>4.1.7. <a href="or-mapping.html#or-mapping-s1-6">version (optional)</a></dt><dt>4.1.8. <a href="or-mapping.html#or-mapping-s1-6b">timestamp (optional)</a></dt><dt>4.1.9. <a href="or-mapping.html#or-mapping-s1-7">property</a></dt><dt>4.1.10. <a href="or-mapping.html#or-mapping-s1-8">many-to-one</a></dt><dt>4.1.11. <a href="or-mapping.html#or-mapping-s1-9">one-to-one</a></dt><dt>4.1.12. <a href="or-mapping.html#or-mapping-s1-10">component, dynabean</a></dt><dt>4.1.13. <a href="or-mapping.html#or-mapping-s1-11">subclass</a></dt><dt>4.1.14. <a href="or-mapping.html#or-mapping-s1-11b">joined-subclass</a></dt><dt>4.1.15. <a href="or-mapping.html#or-mapping-s1-12">map, set, list, bag</a></dt></dl></dd><dt>4.2. <a href="or-mapping.html#or-mapping-s2">Hibernate Types</a></dt><dd><dl><dt>4.2.1. <a href="or-mapping.html#or-mapping-s2-1">Entities and values</a></dt><dt>4.2.2. <a href="or-mapping.html#or-mapping-s2-2">Basic value types</a></dt><dt>4.2.3. <a href="or-mapping.html#or-mapping-s2-3">Persistent enum types</a></dt><dt>4.2.4. <a href="or-mapping.html#or-mapping-s2-4">Custom value types</a></dt><dt>4.2.5. <a href="or-mapping.html#or-mapping-s2-5">The object type</a></dt></dl></dd></dl></dd><dt>5. <a href="adv-or-mapping.html">Advanced O/R Mapping</a></dt><dd><dl><dt>5.1. <a href="adv-or-mapping.html#adv-or-mapping-s1">Collections</a></dt><dd><dl><dt>5.1.1. <a href="adv-or-mapping.html#adv-or-mapping-s1-1">Persistent Collections</a></dt><dt>5.1.2. <a href="adv-or-mapping.html#adv-or-mapping-s1-3">Mapping a Collection</a></dt><dt>5.1.3. <a href="adv-or-mapping.html#adv-or-mapping-s1-5">Collections of Values and Many To Many Associations</a></dt><dt>5.1.4. <a href="adv-or-mapping.html#adv-or-mapping-s1-6">One To Many Associations</a></dt><dt>5.1.5. <a href="adv-or-mapping.html#adv-or-mapping-s1-7">Lazy Initialization</a></dt><dt>5.1.6. <a href="adv-or-mapping.html#adv-or-mapping-s1-8">Sorted Collections</a></dt><dt>5.1.7. <a href="adv-or-mapping.html#adv-or-mapping-s1-9">Garbage Collection</a></dt><dt>5.1.8. <a href="adv-or-mapping.html#adv-or-mapping-s1-10">Bidirectional Associations</a></dt><dt>5.1.9. <a href="adv-or-mapping.html#adv-or-mapping-s1-11">Ternary Associations</a></dt><dt>5.1.10. <a href="adv-or-mapping.html#adv-or-mapping-s1-12">Collection Example</a></dt></dl></dd><dt>5.2. <a href="adv-or-mapping.html#adv-or-mapping-s2">Components</a></dt><dd><dl><dt>5.2.1. <a href="adv-or-mapping.html#adv-or-mapping-s2-1">As Dependent Objects</a></dt><dt>5.2.2. <a href="adv-or-mapping.html#adv-or-mapping-s2-2">In Collections</a></dt><dt>5.2.3. <a href="adv-or-mapping.html#adv-or-mapping-s2-2b">As a Map Index</a></dt><dt>5.2.4. <a href="adv-or-mapping.html#adv-or-mapping-s2-3">As Composite Identifiers</a></dt><dt>5.2.5. <a href="adv-or-mapping.html#adv-or-mapping-s2-4">Dynabean components</a></dt></dl></dd><dt>5.3. <a href="adv-or-mapping.html#adv-or-mapping-s3">Cache</a></dt><dd><dl><dt>5.3.1. <a href="adv-or-mapping.html#adv-or-mapping-s3-1">Mapping</a></dt><dt>5.3.2. <a href="adv-or-mapping.html#adv-or-mapping-s3-2">Read Only Cache</a></dt><dt>5.3.3. <a href="adv-or-mapping.html#adv-or-mapping-s3-3">Read / Write Cache</a></dt></dl></dd><dt>5.4. <a href="adv-or-mapping.html#adv-or-mapping-s4">Proxies for Lazy Initialization</a></dt></dl></dd><dt>6. <a href="manipulating-data.html">Manipulating Persistent Data</a></dt><dd><dl><dt>6.1. <a href="manipulating-data.html#manipulating-data-s1">Creating a persistent object</a></dt><dt>6.2. <a href="manipulating-data.html#manipulating-data-s2">Loading an object</a></dt><dt>6.3. <a href="manipulating-data.html#manipulating-data-s3">Querying</a></dt><dd><dl><dt>6.3.1. <a href="manipulating-data.html#manipulating-data-s4">Scalar queries</a></dt><dt>6.3.2. <a href="manipulating-data.html#manipulating-data-s5">The Query interface</a></dt><dt>6.3.3. <a href="manipulating-data.html#manipulating-data-s5b">Scrollable iteration</a></dt><dt>6.3.4. <a href="manipulating-data.html#manipulating-data-s6">Filtering collections</a></dt></dl></dd><dt>6.4. <a href="manipulating-data.html#manipulating-data-s7">Updating objects saved or loaded in the current session</a></dt><dt>6.5. <a href="manipulating-data.html#manipulating-data-s8">Updating objects saved or loaded in a previous session</a></dt><dt>6.6. <a href="manipulating-data.html#manipulating-data-s9">Deleting persistent objects</a></dt><dt>6.7. <a href="manipulating-data.html#manipulating-data-s10">Graphs of objects</a></dt><dd><dl><dt>6.7.1. <a href="manipulating-data.html#manipulating-data-s11a">Lifecycle objects</a></dt><dt>6.7.2. <a href="manipulating-data.html#manipulating-data-s11b">Persistence by Reachability</a></dt></dl></dd><dt>6.8. <a href="manipulating-data.html#manipulating-data-s12">Flushing</a></dt><dt>6.9. <a href="manipulating-data.html#manipulating-data-s13">Ending a Session</a></dt><dd><dl><dt>6.9.1. <a href="manipulating-data.html#manipulating-data-s13-1">Flushing the session</a></dt><dt>6.9.2. <a href="manipulating-data.html#manipulating-data-s13-2">Committing the transaction</a></dt><dt>6.9.3. <a href="manipulating-data.html#manipulating-data-s13-3">Closing the session</a></dt><dt>6.9.4. <a href="manipulating-data.html#manipulating-data-s13-4">Exception handling</a></dt></dl></dd><dt>6.10. <a href="manipulating-data.html#manipulating-data-s14">Interceptors</a></dt></dl></dd><dt>7. <a href="query-language.html">Hibernate Query Language</a></dt><dd><dl><dt>7.1. <a href="query-language.html#query-language-s1">Case Sensitivity</a></dt><dt>7.2. <a href="query-language.html#query-language-s2">The from clause</a></dt><dt>7.3. <a href="query-language.html#query-language-s3">Associations and joins</a></dt><dt>7.4. <a href="query-language.html#query-language-s4">The select clause</a></dt><dt>7.5. <a href="query-language.html#query-language-s4a">Aggregate functions</a></dt><dt>7.6. <a href="query-language.html#query-language-s4b">polymorphism</a></dt><dt>7.7. <a href="query-language.html#query-language-s5">The where clause</a></dt><dt>7.8. <a href="query-language.html#query-language-s6">Expressions</a></dt><dt>7.9. <a href="query-language.html#query-language-s7">The order by clause</a></dt><dt>7.10. <a href="query-language.html#query-language-s8">The group by clause</a></dt><dt>7.11. <a href="query-language.html#query-language-s9">Subqueries</a></dt></dl></dd><dt>8. <a href="transactions.html">Transactions And Concurrency</a></dt><dd><dl><dt>8.1. <a href="transactions.html#transactions-s1">Configurations, Sessions and Factories</a></dt><dt>8.2. <a href="transactions.html#transactions-s2">Threads and connections</a></dt><dt>8.3. <a href="transactions.html#transactions-s3">Optimistic Locking / Versioning</a></dt><dd><dl><dt>8.3.1. <a href="transactions.html#transactions-s3-1">Long session with automatic versioning</a></dt><dt>8.3.2. <a href="transactions.html#transactions-s3-2">Many sessions with automatic versioning</a></dt><dt>8.3.3. <a href="transactions.html#transactions-s3-3">Application version checking</a></dt></dl></dd><dt>8.4. <a href="transactions.html#transactions-s4">Session disconnection</a></dt><dt>8.5. <a href="transactions.html#transactions-s5">Pessimistic Locking</a></dt></dl></dd><dt>9. <a href="examples.html">Examples</a></dt><dd><dl><dt>9.1. <a href="examples.html#examples-s0">Employer/Employee</a></dt><dt>9.2. <a href="examples.html#examples-s1">Author/Work</a></dt><dt>9.3. <a href="examples.html#examples-s2">Customer/Order/Product</a></dt></dl></dd><dt>10. <a href="best-practices.html">Best Practices</a></dt></dl></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="architecture.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> Chapter 1. Architecture</td></tr></table></div></body></html> \ No newline at end of file Index: query-language.html =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/html/query-language.html,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** query-language.html 23 Feb 2003 13:45:25 -0000 1.3 --- query-language.html 2 Mar 2003 13:59:02 -0000 1.4 *************** *** 8,41 **** <tt class="literal">net.sf.hibernate.eg.FOO</tt> is not <tt class="literal">net.sf.hibernate.eg.Foo</tt> and ! <tt class="literal">foo.Bar</tt> is not ! <tt class="literal">foo.BAR</tt>. </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s2"></a>7.2. The from clause</h2></div></div><div></div></div><p> The simplest possible Hibernate query is of the form: ! </p><pre class="programlisting">from cat in class eg.Cat</pre><p> which simply returns all instances of the class <tt class="literal">eg.Cat</tt>. The query assigns the alias <tt class="literal">cat</tt> to <tt class="literal">Cat</tt> ! instances, so we could use that alias later in the query. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3"></a>7.3. The select clause</h2></div></div><div></div></div><p> ! A multipart <tt class="literal">from</tt> clause is possible. The <tt class="literal">select</tt> ! clause picks which classes to return in the result set. Consider: ! </p><pre class="programlisting">select mate from cat in class eg.Cat, mate in class eg.Cat ! where mate = cat.mate</pre><p> The query will select <tt class="literal">mate</tt>s of other <tt class="literal">Cat</tt>s. Actually, you may express this query more compactly as: ! </p><pre class="programlisting">select cat.mate from cat in class eg.Cat</pre><p>You may even select collection elements:</p><pre class="programlisting">select cat.kittens.elements from cat in class eg.Cat</pre><p> ! Queries may return properties any value type including properties of component type: ! </p><pre class="programlisting">select cat.name from cat in class eg.DomesticCat ! where cat.name like 'fri%'</pre><p> ! You may select multiple objects (Hibernate will return them in an array of type ! <tt class="literal">Object[]</tt>) ! </p><pre class="programlisting">select mother, offspr ! from mother in class eg.DomesticCat, offspr in class eg.Cat ! where offspr in mother.kittens.elements </pre><p> ! Queryies may even return aggregate functions of properties. Collections may also appear ! inside aggregate functions in the <tt class="literal">select</tt> clause. </p><pre class="programlisting">select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from cat in class eg.Cat ! select cat, count(cat.kittens.elements) from cat in class eg.Cat group by cat</pre><p> The supported aggregate functions are </p><div class="itemizedlist"><ul type="disc" compact><li><p> --- 8,86 ---- <tt class="literal">net.sf.hibernate.eg.FOO</tt> is not <tt class="literal">net.sf.hibernate.eg.Foo</tt> and ! <tt class="literal">foo.barSet</tt> is not ! <tt class="literal">foo.BARSET</tt>. </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s2"></a>7.2. The from clause</h2></div></div><div></div></div><p> The simplest possible Hibernate query is of the form: ! </p><pre class="programlisting">from eg.Cat as cat</pre><p> which simply returns all instances of the class <tt class="literal">eg.Cat</tt>. The query assigns the alias <tt class="literal">cat</tt> to <tt class="literal">Cat</tt> ! instances, so we could use that alias later in the query. The <tt class="literal">as</tt> ! keyword is optional; we could also write: ! </p><pre class="programlisting">from eg.Cat cat</pre><p> ! Multiple classes may appear, resulting in a cartesian product or "cross" join. ! </p><pre class="programlisting">from Formula as form, Parameter as param</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3"></a>7.3. Associations and joins</h2></div></div><div></div></div><p> ! We may also define aliases to associated entities using a <tt class="literal">join</tt>. ! </p><pre class="programlisting">from eg.Cat as cat ! inner join cat.mate as mate ! left outer join cat.kittens as kitten ! ! from eg.Cat as cat left join cat.mate.kittens as kittens ! ! from Formula form full join form.parameter param</pre><p> ! The supported join types are borrowed from ANSI SQL ! </p><div class="itemizedlist"><ul type="disc" compact><li><p> ! <tt class="literal">inner join</tt> ! </p></li><li><p> ! <tt class="literal">left outer join</tt> ! </p></li><li><p> ! <tt class="literal">right outer join</tt> (not recommended) ! </p></li><li><p> ! <tt class="literal">full join</tt> (not usually useful) ! </p></li></ul></div><p> ! The <tt class="literal">inner join</tt>, <tt class="literal">left outer join</tt> and ! <tt class="literal">right outer join</tt> constructs may be abbreviated. ! </p><pre class="programlisting">from eg.Cat as cat ! join cat.mate as mate ! left join cat.kittens as kitten</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4"></a>7.4. The select clause</h2></div></div><div></div></div><p> ! The <tt class="literal">select</tt> clause picks which objects and properties to return in ! the query result set. Consider: ! </p><pre class="programlisting">select mate ! from eg.Cat cat ! inner join cat.mate cat</pre><p> The query will select <tt class="literal">mate</tt>s of other <tt class="literal">Cat</tt>s. Actually, you may express this query more compactly as: ! </p><pre class="programlisting">select cat.mate from eg.Cat cat</pre><p> ! You may even select collection elements, using the special <tt class="literal">elements</tt> ! function. The following query returns all kittens of any cat. ! </p><pre class="programlisting">select elements(cat.kittens) from eg.Cat cat</pre><p> ! Queries may return properties of any value type including properties of component type: ! </p><pre class="programlisting">select cat.name from eg.DomesticCat cat ! where cat.name like 'fri%' ! ! select cust.name.firstName from Customer as cust</pre><p> ! Queries may return multiple objects and/or properties as an array of type ! <tt class="literal">Object[]</tt> ! </p><pre class="programlisting">select cat, offspr, mate.name ! from eg.DomesticCat as mother ! inner join mother.mate as mate ! left outer join mother.kittens as offspr</pre><p> ! or as an actual typesafe Java object ! </p><pre class="programlisting">select new Family(cat, mate, offspr) ! from eg.DomesticCat as mother ! join mother.mate as mate ! left join mother.kittens as offspr</pre><p> ! assuming that the class <tt class="literal">Family</tt> has an appropriate constructor. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4a"></a>7.5. Aggregate functions</h2></div></div><div></div></div><p> ! Queryies may even return aggregate functions of properties. </p><pre class="programlisting">select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) ! from eg.Cat cat></programlisting> ! <para> ! Collections may also appear inside aggregate functions in the <literal>select</literal> ! clause. ! </para> ! ! <programlisting><![CDATA[select cat, count( elements(cat.kittens) ) ! from eg.Cat cat group by cat</pre><p> The supported aggregate functions are </p><div class="itemizedlist"><ul type="disc" compact><li><p> *************** *** 48,79 **** The <tt class="literal">distinct</tt> and <tt class="literal">all</tt> keywords may be used and have the same semantics as in SQL. ! </p><pre class="programlisting">select distinct cat.name from cat in class eg.Cat</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s3b"></a>7.4. polymorphism</h2></div></div><div></div></div><p> A query like: ! </p><pre class="programlisting">from cat in class eg.Cat</pre><p> returns instances not only of <tt class="literal">Cat</tt>, but also of subclasses like ! <tt class="literal">DomesticCat</tt>. Hibernate queries may name <span class="emphasis"><em>any</em></span> ! Java class or interface in the <tt class="literal">from</tt> clause. The query will ! return instances of all persistent classes that extend that class or implement ! the interface. The following query would return all persistent objects: ! </p><pre class="programlisting">from o in class java.lang.Object</pre><p> The interface <tt class="literal">Named</tt> might be implemented by various persistent classes: ! </p><pre class="programlisting">from n in class eg.Named, m in class eg.Named where n.name = m.name</pre><p> Note that these last two queries will require more than one SQL <tt class="literal">SELECT</tt>. This means that the <tt class="literal">order by</tt> clause does not correctly order the whole result set. (It also means you can't call these queries using <tt class="literal">Query.scroll()</tt>.) ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4"></a>7.5. from collections</h2></div></div><div></div></div><p> ! You can select entities (but not values) from a collection ! </p><pre class="programlisting">select kitten from ! cat in class eg.Cat, ! kitten in cat.kittens.elements</pre><p> ! The <tt class="literal">elements</tt> construct is like a special property referring to the ! element set of the collection. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s5"></a>7.6. The where clause</h2></div></div><div></div></div><p> ! The <tt class="literal">where</tt> clause allows you to narrow the list ! of instances returned. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.name='Fritz'</pre><p> returns instances of <tt class="literal">Cat</tt> named 'Fritz'. ! </p><pre class="programlisting">select foo from foo in class eg.Foo, bar in class eg.Bar where foo.startDate = bar.date</pre><p> will return all instances of <tt class="literal">Foo</tt> for which --- 93,118 ---- The <tt class="literal">distinct</tt> and <tt class="literal">all</tt> keywords may be used and have the same semantics as in SQL. ! </p><pre class="programlisting">select distinct cat.name from eg.Cat cat ! ! select count(distinct cat.name), count(cat) from eg.Cat cat</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s4b"></a>7.6. polymorphism</h2></div></div><div></div></div><p> A query like: ! </p><pre class="programlisting">from eg.Cat as cat</pre><p> returns instances not only of <tt class="literal">Cat</tt>, but also of subclasses like ! <tt class="literal">DomesticCat</tt>. Hibernate queries may name <span class="emphasis"><em>any</em></span> Java ! class or interface in the <tt class="literal">from</tt> clause. The query will return instances ! of all persistent classes that extend that class or implement the interface. The following ! query would return all persistent objects: ! </p><pre class="programlisting">from java.lang.Object o</pre><p> The interface <tt class="literal">Named</tt> might be implemented by various persistent classes: ! </p><pre class="programlisting">from eg.Named n, eg.Named m where n.name = m.name</pre><p> Note that these last two queries will require more than one SQL <tt class="literal">SELECT</tt>. This means that the <tt class="literal">order by</tt> clause does not correctly order the whole result set. (It also means you can't call these queries using <tt class="literal">Query.scroll()</tt>.) ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s5"></a>7.7. The where clause</h2></div></div><div></div></div><p> ! The <tt class="literal">where</tt> clause allows you to narrow the list of instances returned. ! </p><pre class="programlisting">from eg.Cat as cat where cat.name='Fritz'</pre><p> returns instances of <tt class="literal">Cat</tt> named 'Fritz'. ! </p><pre class="programlisting">select foo from eg.Foo foo, eg.Bar bar where foo.startDate = bar.date</pre><p> will return all instances of <tt class="literal">Foo</tt> for which *************** *** 83,90 **** <tt class="literal">Foo</tt>. Compound path expressions make the <tt class="literal">where</tt> clause extremely powerful. Consider: ! </p><pre class="programlisting">from cat in class eg.Cat where cat.mate.name is not null</pre><p> ! This query translates to an SQL query with a table join. If you were to write something like ! </p><pre class="programlisting">from foo in class eg.Foo where foo.bar.baz.customer.address.city is not null</pre><p> you would end up with a query that would require four table joins in SQL. --- 122,129 ---- <tt class="literal">Foo</tt>. Compound path expressions make the <tt class="literal">where</tt> clause extremely powerful. Consider: ! </p><pre class="programlisting">from eg.Cat cat where cat.mate.name is not null</pre><p> ! This query translates to an SQL query with a table (inner) join. If you were to write something like ! </p><pre class="programlisting">from eg.Foo foo where foo.bar.baz.customer.address.city is not null</pre><p> you would end up with a query that would require four table joins in SQL. *************** *** 92,104 **** The <tt class="literal">=</tt> operator may be used to compare not only properties, but also instances: ! </p><pre class="programlisting">from cat in class eg.Cat, rival in class eg.Cat where cat.mate = rival.mate ! select cat, mate from cat in class eg.Cat, mate in class eg.Cat where cat.mate = mate</pre><p> The special property (lowercase) <tt class="literal">id</tt> may be used to reference the unique identifier of an object. (You may also use its property name.) ! </p><pre class="programlisting">from cat in class eg.Cat where cat.id = 123 ! from cat in class eg.Cat where cat.mate.id = 69</pre><p> The second query is efficient. No table join is required! </p><p> --- 131,143 ---- The <tt class="literal">=</tt> operator may be used to compare not only properties, but also instances: ! </p><pre class="programlisting">from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate ! select cat, mate from eg.Cat cat, eg.Cat mate where cat.mate = mate</pre><p> The special property (lowercase) <tt class="literal">id</tt> may be used to reference the unique identifier of an object. (You may also use its property name.) ! </p><pre class="programlisting">from eg.Cat as cat where cat.id = 123 ! from eg.Cat as cat where cat.mate.id = 69</pre><p> The second query is efficient. No table join is required! </p><p> *************** *** 106,113 **** has a composite identifier consisting of <tt class="literal">country</tt> and <tt class="literal">medicareNumber</tt>. ! </p><pre class="programlisting">from person in class bank.Person where person.id.country = 'AU' and person.id.medicareNumber = 123456 ! from account in class bank.Account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> Once again, the second query requires no table join. --- 145,152 ---- has a composite identifier consisting of <tt class="literal">country</tt> and <tt class="literal">medicareNumber</tt>. ! </p><pre class="programlisting">from bank.Person person where person.id.country = 'AU' and person.id.medicareNumber = 123456 ! from bank.Account account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456</pre><p> Once again, the second query requires no table join. *************** *** 116,120 **** of an instance in the case of polymorphic persistence. A Java class name embedded in the where clause will be translated to its discriminator value. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.class = eg.DomesticCat</pre><p> You may also specify properties of components (and of components of components). Never try to use a path-expression that ends in a property of component type --- 155,159 ---- of an instance in the case of polymorphic persistence. A Java class name embedded in the where clause will be translated to its discriminator value. ! </p><pre class="programlisting">from eg.Cat cat where cat.class = eg.DomesticCat</pre><p> You may also specify properties of components (and of components of components). Never try to use a path-expression that ends in a property of component type *************** *** 122,126 **** is an entity with a component <tt class="literal">address</tt> </p><pre class="programlisting">store.owner.address.city //okay ! store.owner.address //error!</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s6"></a>7.7. Expressions</h2></div></div><div></div></div><p> Expressions allowed in the <tt class="literal">where</tt> clause include most of the kind of things you could write in SQL: --- 161,165 ---- is an entity with a component <tt class="literal">address</tt> </p><pre class="programlisting">store.owner.address.city //okay ! store.owner.address //error!</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s6"></a>7.8. Expressions</h2></div></div><div></div></div><p> Expressions allowed in the <tt class="literal">where</tt> clause include most of the kind of things you could write in SQL: *************** *** 152,188 **** </p></li></ul></div><p> <tt class="literal">in</tt> and <tt class="literal">between</tt> may be used as follows: ! </p><pre class="programlisting">from cat in class eg.DomesticCat where cat.name between 'A' and 'B' ! from cat in class eg.DomesticCat where cat.name in ( 'Foo', 'Bar', Baz" )</pre><p> and the negated forms may be written ! </p><pre class="programlisting">from cat in class eg.DomesticCat where cat.name not between 'A' and 'B' ! from cat in class eg.DomesticCat where cat.name not in ( 'Foo', 'Bar', Baz" )</pre><p> Likewise, <tt class="literal">is null</tt> and <tt class="literal">is not null</tt> may be used to test for null values. </p><p> ! You may test the size of a collection with the special property <tt class="literal">size</tt> ! </p><pre class="programlisting">from cat in class eg.Cat where cat.kittens.size > 0</pre><p> For indexed collections, you may refer to the minimum and maximum indices using <tt class="literal">minIndex</tt> and <tt class="literal">maxIndex</tt>. Similarly, you may refer to the minimum and maximum elements of a collection of basic type using <tt class="literal">minElement</tt> and <tt class="literal">maxElement</tt>. ! </p><pre class="programlisting">from cal in class Calendar where cal.holidays.maxElement > current date</pre><p> ! The SQL functions <tt class="literal">any, some, all, exists, in</tt> are supported when passed one of ! two special properties of a collection. The special properties are <tt class="literal">elements</tt> and ! <tt class="literal">indices</tt>. Respectively they represent the element set and the index set of the ! collection. ! </p><pre class="programlisting">select mother from mother in class eg.Cat, kit in class eg.Cat ! where kit in foo.kittens.elements ! select p from list in class eg.NameList, p in class eg.Person ! where p.name = some list.names.elements ! from cat in class eg.Cat where exists cat.kittens.elements ! from p in class eg.Player where 3 > all p.scores.elements ! from show in class eg.Show ! where 'fizard' in show.acts.indices</pre><p> Note that these constructs - <tt class="literal">size</tt>, <tt class="literal">elements</tt>, <tt class="literal">indices</tt>, <tt class="literal">minIndex</tt>, <tt class="literal">maxIndex</tt>, --- 191,232 ---- </p></li></ul></div><p> <tt class="literal">in</tt> and <tt class="literal">between</tt> may be used as follows: ! </p><pre class="programlisting">from eg.DomesticCat cat where cat.name between 'A' and 'B' ! from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar', Baz" )</pre><p> and the negated forms may be written ! </p><pre class="programlisting">from eg.DomesticCat cat where cat.name not between 'A' and 'B' ! from eg.DomesticCat cat where cat.name not in ( 'Foo', 'Bar', Baz" )</pre><p> Likewise, <tt class="literal">is null</tt> and <tt class="literal">is not null</tt> may be used to test for null values. </p><p> ! You may test the size of a collection with the special property <tt class="literal">size</tt>, or ! the special <tt class="literal">size()</tt> function. ! </p><pre class="programlisting">from eg.Cat cat where cat.kittens.size > 0 ! ! from eg.Cat cat where size(cat.kittens) > 0</pre><p> For indexed collections, you may refer to the minimum and maximum indices using <tt class="literal">minIndex</tt> and <tt class="literal">maxIndex</tt>. Similarly, you may refer to the minimum and maximum elements of a collection of basic type using <tt class="literal">minElement</tt> and <tt class="literal">maxElement</tt>. ! </p><pre class="programlisting">from Calendar cal where cal.holidays.maxElement > current date</pre><p> ! There are also functional forms (which, unlike the constructs above, are not case sensitive): ! </p><pre class="programlisting">from Order order where maxindex(order.items) > 100 ! from Order order where minelement(order.items) > 10000</pre><p> ! The SQL functions <tt class="literal">any, some, all, exists, in</tt> are supported when passed the element ! or index set of a collection (<tt class="literal">elements</tt> and <tt class="literal">indices</tt> functions) ! or the result of a subquery (see below). ! </p><pre class="programlisting">select mother from eg.Cat as mother, eg.Cat as kit ! where kit in elements(foo.kittens) ! select p from eg.NameList list, eg.Person p ! where p.name = some elements(list.names) ! from eg.Cat cat where exists elements(cat.kittens) ! from eg.Player p where 3 > all elements(p.scores) ! ! from eg.Show show where 'fizard' in indices(show.acts)</pre><p> Note that these constructs - <tt class="literal">size</tt>, <tt class="literal">elements</tt>, <tt class="literal">indices</tt>, <tt class="literal">minIndex</tt>, <tt class="literal">maxIndex</tt>, *************** *** 192,226 **** in a <tt class="literal">where</tt> clause: only for databases with subselects </p></li><li><p> - in a <tt class="literal">from</tt> clause: only <tt class="literal">elements</tt> makes sense ... and - only for a collection of entities - </p></li><li><p> in a <tt class="literal">select</tt> clause: only <tt class="literal">elements</tt> and <tt class="literal">indices</tt> make sense </p></li></ul></div><p> Elements of indexed collections (arrays, lists, maps) may be referred to by index (in a where clause only) ! </p><pre class="programlisting">from order in class Order where order.items[0].id = 1234 ! select person from person in class Person, calendar in class Calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar ! select item from item in class Item, order in class Order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 ! select item from item in class Item, order in class Order ! where order.items[order.items.maxIndex] = item and order.id = 11</pre><p> The expression inside <tt class="literal">[]</tt> may even be an arithmetic expression. ! </p><p> Scalar SQL functions supported by the underlying database may be used ! </p><pre class="programlisting">from cat in class eg.DomesticCat where upper(cat.name) like 'FRI%'</pre><p> If you are not yet convinced by all this, think how much longer and less readable the following query would be in SQL: </p><pre class="programlisting">select cust ! from prod in class Product, ! store in class Store, ! cust in store.customers where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) ! and prod = all cust.currentOrder.lineItems.elements</pre><p> <span class="emphasis"><em>Hint:</em></span> something like </p><pre class="programlisting">SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order --- 236,268 ---- in a <tt class="literal">where</tt> clause: only for databases with subselects </p></li><li><p> in a <tt class="literal">select</tt> clause: only <tt class="literal">elements</tt> and <tt class="literal">indices</tt> make sense </p></li></ul></div><p> Elements of indexed collections (arrays, lists, maps) may be referred to by index (in a where clause only) ! </p><pre class="programlisting">from Order order where order.items[0].id = 1234 ! select person from Person person, Calendar calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar ! select item from Item item, Order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11 ! select item from Item item, Order order ! where order.items[ maxindex(order.items) ] = item and order.id = 11</pre><p> The expression inside <tt class="literal">[]</tt> may even be an arithmetic expression. ! </p><pre class="programlisting">select item from Item item, Order order ! where order.items[ size(order.items) - 1 ] = item</pre><p> Scalar SQL functions supported by the underlying database may be used ! </p><pre class="programlisting">from eg.DomesticCat cat where upper(cat.name) like 'FRI%'</pre><p> If you are not yet convinced by all this, think how much longer and less readable the following query would be in SQL: </p><pre class="programlisting">select cust ! from Product prod, ! Store store ! inner join store.customers cust where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) ! and prod = all elements(cust.currentOrder.lineItems)</pre><p> <span class="emphasis"><em>Hint:</em></span> something like </p><pre class="programlisting">SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order *************** *** 240,266 **** WHERE item.order_id = o.id AND cust.current_order = o.id ! )</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s7"></a>7.8. The order by clause</h2></div></div><div></div></div><p> The list returned by a query may be ordered by any property of a returned class or components: ! </p><pre class="programlisting">from cat in class eg.DomesticCat order by cat.name asc, cat.weight desc, cat.birthdate</pre><p> The optional <tt class="literal">asc</tt> or <tt class="literal">desc</tt> indicate ascending or descending order respectively. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s8"></a>7.9. The group by clause</h2></div></div><div></div></div><p> A query that returns aggregate values may be grouped by any property of a returned class or components: ! </p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from cat in class eg.Cat group by cat.color ! select foo.id, avg(foo.names.elements), max(foo.names.indices) from foo in class eg.Foo group by foo.id</pre><p>Note: You may use the <tt class="literal">elements</tt> and <tt class="literal">indices</tt> constructs ! inside a select clause, even on databases with no subselects.</p><p>A <tt class="literal">having</tt> clause is also allowed.</p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from foo in class eg.Foo ! group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s9"></a>7.10. Subqueries</h2></div></div><div></div></div><p> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). eg. ! </p><pre class="programlisting">from cat in class eg.Cat where cat.weight > ! ( select avg(cat.weight) from cat in class eg.DomesticCat ) ! from cat in class eg.DomesticCat where cat.name = ! some( select list.name from list in class eg.NameList ) ! from cat in class eg.Cat where not exists ! ( from mate in class eg.Cat where mate.mate = cat )</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manipulating-data.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="transactions.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 6. Manipulating Persistent Data </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 8. Transactions And Concurrency</td></tr></table></div></body></html> \ No newline at end of file --- 282,309 ---- WHERE item.order_id = o.id AND cust.current_order = o.id ! )</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s7"></a>7.9. The order by clause</h2></div></div><div></div></div><p> The list returned by a query may be ordered by any property of a returned class or components: ! </p><pre class="programlisting">from eg.DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate</pre><p> The optional <tt class="literal">asc</tt> or <tt class="literal">desc</tt> indicate ascending or descending order respectively. ! </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s8"></a>7.10. The group by clause</h2></div></div><div></div></div><p> A query that returns aggregate values may be grouped by any property of a returned class or components: ! </p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from eg.Cat cat group by cat.color ! select foo.id, avg( elements(foo.names) ), max( indices(foo.names) ) from eg.Foo foo group by foo.id</pre><p>Note: You may use the <tt class="literal">elements</tt> and <tt class="literal">indices</tt> constructs ! inside a select clause, even on databases with no subselects.</p><p>A <tt class="literal">having</tt> clause is also allowed.</p><pre class="programlisting">select cat.color, sum(cat.weight), count(cat) from eg.Cat cat ! group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)</pre></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="query-language-s9"></a>7.11. Subqueries</h2></div></div><div></div></div><p> For databases that support subselects, Hibernate supports subqueries within queries. A subquery must ! be surrounded by parentheses (often by an SQL aggregate function call). Even /correlated/ subqueries ! (subqueries that refer to an alias in the outer query) are allowed. ! </p><pre class="programlisting">from eg.Cat fatcat where fatcat.weight > ! ( select avg(cat.weight) from eg.DomesticCat cat ) ! from eg.DomesticCat cat where cat.name = ! some( select list.name from eg.NameList list ) ! from eg.Cat cat where not exists ! ( from eg.Cat mate where mate.mate = cat )</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manipulating-data.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="transactions.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top... [truncated message content] |
From: <tu...@us...> - 2003-03-02 13:59:05
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/pdf In directory sc8-pr-cvs1:/tmp/cvs-serv23405/doc/reference/pdf Modified Files: hibernate_reference.pdf Log Message: Version Update for Release Index: hibernate_reference.pdf =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/pdf/hibernate_reference.pdf,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** hibernate_reference.pdf 23 Feb 2003 13:48:53 -0000 1.3 --- hibernate_reference.pdf 2 Mar 2003 13:59:01 -0000 1.4 *************** *** 6,13 **** endobj 5 0 obj ! << /Length 221 /Filter [ /ASCII85Decode /FlateDecode ] >> stream ! Gaq4K4V*-0$jPY'^S2q]f'@a9,=*"!1`$tgJE/Bo5XbPMSq8++Rc_ll,V;,p4Zl$nQ@tMOiimH61P^]V8;1(`;Tr7PYhljJAIh9Z4KNac;Na<&JG?8c"Q"\W"5,D#Q_DMY)9:rF]HjE%KHYG[89#B^fLj<#I^c!iX7=S].:1CDIPfCChigNk1==R:Up6,-%`9gJ2@C=*bAdo"-"f$Jq#MkC24X~> endstream endobj --- 6,13 ---- endobj [...6200 lines suppressed...] ! 0000368005 00000 n ! 0000368247 00000 n ! 0000368485 00000 n ! 0000368599 00000 n ! 0000368685 00000 n ! 0000368796 00000 n ! 0000368912 00000 n ! 0000369024 00000 n ! 0000369133 00000 n ! 0000369246 00000 n ! 0000369353 00000 n trailer << ! /Size 506 /Root 2 0 R /Info 4 0 R >> startxref ! 378282 %%EOF |