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: <hib...@li...> - 2006-07-24 10:52:08
|
Author: max...@jb...
Date: 2006-07-24 06:52:04 -0400 (Mon, 24 Jul 2006)
New Revision: 10138
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java
Log:
proper naming
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-07-24 10:51:54 UTC (rev 10137)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-07-24 10:52:04 UTC (rev 10138)
@@ -168,7 +168,7 @@
s.close();
}
- public void testParameterTypeMismatchFails() {
+ public void testParameterTypeMismatchFailureExpected() {
Session s = openSession();
s.beginTransaction();
@@ -291,7 +291,7 @@
s.close();
}
- public void testFetchInSubqueryFails() {
+ public void testFetchInSubqueryFailureExpected() {
Session s = openSession();
try {
s.createQuery( "from Animal a where a.mother in (select m from Animal a1 inner join a1.mother as m join fetch m.mother)" ).list();
|
|
From: <hib...@li...> - 2006-07-24 10:51:58
|
Author: max...@jb...
Date: 2006-07-24 06:51:54 -0400 (Mon, 24 Jul 2006)
New Revision: 10137
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
Log:
mingled order of types in exception message
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java 2006-07-24 10:46:07 UTC (rev 10136)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java 2006-07-24 10:51:54 UTC (rev 10137)
@@ -519,8 +519,8 @@
catch( ClassCastException cce ) {
throw new TypeMismatchException(
"named parameter [" + name + "] not of expected type; expected = " +
- typedval.getValue().getClass().getName() + "; but was =" +
- typedval.getType().getReturnedClass()
+ typedval.getType().getReturnedClass() + "; but was =" +
+ typedval.getValue().getClass().getName()
);
}
}
|
|
From: <hib...@li...> - 2006-07-24 10:46:10
|
Author: max...@jb...
Date: 2006-07-24 06:46:07 -0400 (Mon, 24 Jul 2006)
New Revision: 10136
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
Log:
HHH-1924 ForeignKeys: TransientObjectException is thrown without a message because of a wrong bracket in the code
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-07-24 10:37:21 UTC (rev 10135)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-07-24 10:46:07 UTC (rev 10136)
@@ -218,7 +218,7 @@
if ( isTransient(entityName, object, Boolean.FALSE, session) ) {
throw new TransientObjectException(
"object references an unsaved transient instance - save the transient instance before flushing: " +
- entityName == null ? session.guessEntityName( object ) : entityName
+ (entityName == null ? session.guessEntityName( object ) : entityName)
);
}
id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() );
|
|
From: <hib...@li...> - 2006-07-24 10:37:33
|
Author: max...@jb...
Date: 2006-07-24 06:37:21 -0400 (Mon, 24 Jul 2006)
New Revision: 10135
Modified:
trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java
Log:
proper naming
Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-07-24 10:36:54 UTC (rev 10134)
+++ trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-07-24 10:37:21 UTC (rev 10135)
@@ -168,7 +168,7 @@
s.close();
}
- public void testParameterTypeMismatchFails() {
+ public void testParameterTypeMismatchFailureExpected() {
Session s = openSession();
s.beginTransaction();
|
|
From: <hib...@li...> - 2006-07-24 10:37:03
|
Author: max...@jb...
Date: 2006-07-24 06:36:54 -0400 (Mon, 24 Jul 2006)
New Revision: 10134
Modified:
trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
Log:
mingled order of types in exception message
Modified: trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java 2006-07-24 10:35:25 UTC (rev 10133)
+++ trunk/Hibernate3/src/org/hibernate/loader/hql/QueryLoader.java 2006-07-24 10:36:54 UTC (rev 10134)
@@ -519,8 +519,8 @@
catch( ClassCastException cce ) {
throw new TypeMismatchException(
"named parameter [" + name + "] not of expected type; expected = " +
- typedval.getValue().getClass().getName() + "; but was =" +
- typedval.getType().getReturnedClass()
+ typedval.getType().getReturnedClass() + "; but was =" +
+ typedval.getValue().getClass().getName()
);
}
}
|
|
From: <hib...@li...> - 2006-07-24 10:35:38
|
Author: max...@jb...
Date: 2006-07-24 06:35:25 -0400 (Mon, 24 Jul 2006)
New Revision: 10133
Modified:
trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
Log:
HHH-1924 ForeignKeys: TransientObjectException is thrown without a message because of a wrong bracket in the code
Modified: trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-07-21 16:53:54 UTC (rev 10132)
+++ trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-07-24 10:35:25 UTC (rev 10133)
@@ -218,7 +218,7 @@
if ( isTransient(entityName, object, Boolean.FALSE, session) ) {
throw new TransientObjectException(
"object references an unsaved transient instance - save the transient instance before flushing: " +
- entityName == null ? session.guessEntityName( object ) : entityName
+ (entityName == null ? session.guessEntityName( object ) : entityName)
);
}
id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() );
|
|
From: <hib...@li...> - 2006-07-21 16:54:29
|
Author: ste...@jb...
Date: 2006-07-21 12:53:54 -0400 (Fri, 21 Jul 2006)
New Revision: 10132
Added:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
Log:
port fix for HHH-1927 to 3.2 branch
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-21 16:52:30 UTC (rev 10131)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-21 16:53:54 UTC (rev 10132)
@@ -17,6 +17,8 @@
import org.hibernate.event.MergeEvent;
import org.hibernate.event.MergeEventListener;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.persister.entity.EntityPersister;
@@ -85,14 +87,33 @@
event.setResult(entity);
}
else {
- event.setEntity(entity);
-
- int entityState = getEntityState(
- entity,
- event.getEntityName(),
- source.getPersistenceContext().getEntry(entity),
- source
- );
+ event.setEntity( entity );
+ int entityState = -1;
+
+ // Check the persistence context for an entry relating to this
+ // entity to be merged...
+ EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+ if ( entry == null ) {
+ EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+ Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+ if ( id != null ) {
+ EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+ Object managedEntity = source.getPersistenceContext().getEntity( key );
+ entry = source.getPersistenceContext().getEntry( managedEntity );
+ if ( entry != null ) {
+ // we have specialized case of a detached entity from the
+ // perspective of the merge operation. Specifically, we
+ // have an incoming entity instance which has a corresponding
+ // entry in the current persistence context, but registered
+ // under a different entity instance
+ entityState = DETACHED;
+ }
+ }
+ }
+
+ if ( entityState == -1 ) {
+ entityState = getEntityState( entity, event.getEntityName(), entry, source );
+ }
switch (entityState) {
case DETACHED:
@@ -263,13 +284,50 @@
}
private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) {
- return persister.isVersioned() &&
- !persister.getVersionType().isSame(
- persister.getVersion( target, source.getEntityMode() ),
- persister.getVersion( entity, source.getEntityMode() ),
- source.getEntityMode()
- );
+ if ( ! persister.isVersioned() ) {
+ return false;
+ }
+ // for merging of versioned entities, we consider the version having
+ // been changed only when:
+ // 1) the two version values are different;
+ // *AND*
+ // 2) The target actually represents database state!
+ //
+ // This second condition is a special case which allows
+ // an entity to be merged during the same transaction
+ // (though during a seperate operation) in which it was
+ // originally persisted/saved
+ boolean changed = persister.getVersionType().isSame(
+ persister.getVersion( target, source.getEntityMode() ),
+ persister.getVersion( entity, source.getEntityMode() ),
+ source.getEntityMode()
+ );
+
+ // TODO : perhaps we should additionally require that the incoming entity
+ // version be equivalent to the defined unsaved-value?
+ return changed && existsInDatabase( target, source, persister );
}
+
+ private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
+ EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+ if ( entry == null ) {
+ Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+ if ( id != null ) {
+ EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+ Object managedEntity = source.getPersistenceContext().getEntity( key );
+ entry = source.getPersistenceContext().getEntry( managedEntity );
+ }
+ }
+
+ if ( entry == null ) {
+ // perhaps this should be an exception since it is only ever used
+ // in the above method?
+ return false;
+ }
+ else {
+ return entry.isExistsInDatabase();
+ }
+ }
protected void copyValues(
final EntityPersister persister,
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-07-21 16:52:30 UTC (rev 10131)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-07-21 16:53:54 UTC (rev 10132)
@@ -9,6 +9,7 @@
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.NonUniqueObjectException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Projections;
@@ -22,6 +23,58 @@
public MergeTest(String str) {
super(str);
}
+
+ public void testPersistThenMergeInSameTxnWithVersion() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ VersionedEntity entity = new VersionedEntity( "test", "test" );
+ s.persist( entity );
+ s.merge( new VersionedEntity( "test", "test-2" ) );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( entity );
+ tx.commit();
+ s.close();
+ }
+
+ public void testPersistThenMergeInSameTxnWithTimestamp() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ TimestampedEntity entity = new TimestampedEntity( "test", "test" );
+ s.persist( entity );
+ s.merge( new TimestampedEntity( "test", "test-2" ) );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( entity );
+ tx.commit();
+ s.close();
+ }
public void testMergeDeepTree() {
@@ -330,7 +383,7 @@
}
protected String[] getMappings() {
- return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml" };
+ return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml", "ops/OptLockEntity.hbm.xml" };
}
public static Test suite() {
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-07-21 16:52:30 UTC (rev 10131)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-07-21 16:53:54 UTC (rev 10132)
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.ops">
+
+ <class name="VersionedEntity" table="V_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="name" column="NAME" type="string" />
+ </class>
+
+ <class name="TimestampedEntity" table="T_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <timestamp name="timestamp" column="TS" />
+ <property name="name" column="NAME" type="string" />
+ </class>
+
+</hibernate-mapping>
+
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java 2006-07-21 16:52:30 UTC (rev 10131)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java 2006-07-21 16:53:54 UTC (rev 10132)
@@ -0,0 +1,47 @@
+package org.hibernate.test.ops;
+
+import java.util.Date;
+
+/**
+ * todo: describe TimestampedEntity
+ *
+ * @author Steve Ebersole
+ */
+public class TimestampedEntity {
+ private String id;
+ private String name;
+ private Date timestamp;
+
+ public TimestampedEntity() {
+ }
+
+ public TimestampedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+}
+
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java 2006-07-21 16:52:30 UTC (rev 10131)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java 2006-07-21 16:53:54 UTC (rev 10132)
@@ -0,0 +1,44 @@
+package org.hibernate.test.ops;
+
+/**
+ * todo: describe VersionedEntity
+ *
+ * @author Steve Ebersole
+ */
+public class VersionedEntity {
+ private String id;
+ private String name;
+ private long version;
+
+ public VersionedEntity() {
+ }
+
+ public VersionedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+}
|
|
From: <hib...@li...> - 2006-07-21 16:53:05
|
Author: ste...@jb...
Date: 2006-07-21 12:52:30 -0400 (Fri, 21 Jul 2006)
New Revision: 10131
Modified:
trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
Log:
different approach to HHH-1927
Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-07-21 07:10:41 UTC (rev 10130)
+++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-07-21 16:52:30 UTC (rev 10131)
@@ -453,24 +453,6 @@
EntityEntry entry, //pass this as an argument only to avoid double looking
SessionImplementor source) {
- if ( entry == null && performDeepStateChecking() ) {
- // check to handle fringe case of merging the same "entity data" via
- // a transient instance within the same transaction it was saved; i.e.:
- // Session s = ...;
- // s.beginTransaction();
- // s.persist( new Entity( "someid" ) );
- // s.merge( new Entity( "someid" ) );
- // s.getTransaction().commit();
- EntityPersister persister = source.getEntityPersister( entityName, entity );
- Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
- if ( id != null ) {
- EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
- entry = source.getPersistenceContext().getEntry(
- source.getPersistenceContext().getEntity( key )
- );
- }
- }
-
if ( entry != null ) {
// the object is persistent as it has an entry associated with the
// session; so check its status
@@ -529,8 +511,4 @@
protected Boolean getAssumedUnsaved() {
return null;
}
-
- protected boolean performDeepStateChecking() {
- return false;
- }
}
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-21 07:10:41 UTC (rev 10130)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-21 16:52:30 UTC (rev 10131)
@@ -17,6 +17,8 @@
import org.hibernate.event.MergeEvent;
import org.hibernate.event.MergeEventListener;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.persister.entity.EntityPersister;
@@ -85,15 +87,36 @@
event.setResult(entity);
}
else {
- event.setEntity(entity);
-
- int entityState = getEntityState(
- entity,
- event.getEntityName(),
- source.getPersistenceContext().getEntry(entity),
- source
- );
-
+
+ event.setEntity( entity );
+
+ int entityState = -1;
+
+ // Check the persistence context for an entry relating to this
+ // entity to be merged...
+ EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+ if ( entry == null ) {
+ EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+ Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+ if ( id != null ) {
+ EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+ Object managedEntity = source.getPersistenceContext().getEntity( key );
+ entry = source.getPersistenceContext().getEntry( managedEntity );
+ if ( entry != null ) {
+ // we have specialized case of a detached entity from the
+ // perspective of the merge operation. Specifically, we
+ // have an incoming entity instance which has a corresponding
+ // entry in the current persistence context, but registered
+ // under a different entity instance
+ entityState = DETACHED;
+ }
+ }
+ }
+
+ if ( entityState == -1 ) {
+ entityState = getEntityState( entity, event.getEntityName(), entry, source );
+ }
+
switch (entityState) {
case DETACHED:
entityIsDetached(event, copyCache);
@@ -117,10 +140,6 @@
}
- protected boolean performDeepStateChecking() {
- return true;
- }
-
protected void entityIsPersistent(MergeEvent event, Map copyCache) {
log.trace("ignoring persistent instance");
@@ -151,7 +170,7 @@
final Serializable id = persister.hasIdentifierProperty() ?
persister.getIdentifier( entity, source.getEntityMode() ) :
null;
-
+
final Object copy = persister.instantiate( id, source.getEntityMode() ); //TODO: should this be Session.instantiate(Persister, ...)?
copyCache.put(entity, copy); //before cascade!
@@ -267,14 +286,51 @@
}
private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) {
- return persister.isVersioned() &&
- !persister.getVersionType().isSame(
- persister.getVersion( target, source.getEntityMode() ),
- persister.getVersion( entity, source.getEntityMode() ),
- source.getEntityMode()
- );
+ if ( ! persister.isVersioned() ) {
+ return false;
+ }
+ // for merging of versioned entities, we consider the version having
+ // been changed only when:
+ // 1) the two version values are different;
+ // *AND*
+ // 2) The target actually represents database state!
+ //
+ // This second condition is a special case which allows
+ // an entity to be merged during the same transaction
+ // (though during a seperate operation) in which it was
+ // originally persisted/saved
+ boolean changed = persister.getVersionType().isSame(
+ persister.getVersion( target, source.getEntityMode() ),
+ persister.getVersion( entity, source.getEntityMode() ),
+ source.getEntityMode()
+ );
+
+ // TODO : perhaps we should additionally require that the incoming entity
+ // version be equivalent to the defined unsaved-value?
+ return changed && existsInDatabase( target, source, persister );
}
-
+
+ private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
+ EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+ if ( entry == null ) {
+ Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+ if ( id != null ) {
+ EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+ Object managedEntity = source.getPersistenceContext().getEntity( key );
+ entry = source.getPersistenceContext().getEntry( managedEntity );
+ }
+ }
+
+ if ( entry == null ) {
+ // perhaps this should be an exception since it is only ever used
+ // in the above method?
+ return false;
+ }
+ else {
+ return entry.isExistsInDatabase();
+ }
+ }
+
protected void copyValues(
final EntityPersister persister,
final Object entity,
|
|
From: <hib...@li...> - 2006-07-21 07:10:45
|
Author: chr...@jb...
Date: 2006-07-21 03:10:41 -0400 (Fri, 21 Jul 2006)
New Revision: 10130
Modified:
trunk/Hibernate3/doc/reference/build.xml
Log:
Updated current status
Modified: trunk/Hibernate3/doc/reference/build.xml
===================================================================
--- trunk/Hibernate3/doc/reference/build.xml 2006-07-21 06:41:22 UTC (rev 10129)
+++ trunk/Hibernate3/doc/reference/build.xml 2006-07-21 07:10:41 UTC (rev 10130)
@@ -40,12 +40,13 @@
<!-- TRANSLATOR: Duplicate this line for your language -->
<antcall target="lang.all"><param name="lang" value="en"/></antcall>
- <antcall target="lang.all"><param name="lang" value="fr"/></antcall>
- <antcall target="lang.all"><param name="lang" value="ko"/></antcall>
+ <!-- TODO: These translations need updating...
<antcall target="lang.all"><param name="lang" value="zh-cn"/></antcall>
- <!-- TODO: These translations need updating...
<antcall target="lang.all"><param name="lang" value="es"/></antcall>
- -->
+ <antcall target="lang.all"><param name="lang" value="ja"/></antcall>
+ <antcall target="lang.all"><param name="lang" value="ko"/></antcall>
+ <antcall target="lang.all"><param name="lang" value="fr"/></antcall>
+ -->
</target>
@@ -55,7 +56,8 @@
<!-- TRANSLATOR: Duplicate this line for your language -->
<antcall target="lang.revdiff"><param name="lang" value="zh-cn"/></antcall>
<antcall target="lang.revdiff"><param name="lang" value="es"/></antcall>
- <antcall target="lang.revdiff"><param name="lang" value="ko"/></antcall>
+ <antcall target="lang.revdiff"><param name="lang" value="ja"/></antcall>
+ <antcall target="lang.revdiff"><param name="lang" value="ko"/></antcall>
<antcall target="lang.revdiff"><param name="lang" value="fr"/></antcall>
</target>
|
|
From: <hib...@li...> - 2006-07-21 06:41:28
|
Author: chr...@jb...
Date: 2006-07-21 02:41:22 -0400 (Fri, 21 Jul 2006)
New Revision: 10129
Modified:
trunk/Hibernate3/doc/reference/en/modules/tutorial.xml
Log:
HHH-1906
Modified: trunk/Hibernate3/doc/reference/en/modules/tutorial.xml
===================================================================
--- trunk/Hibernate3/doc/reference/en/modules/tutorial.xml 2006-07-20 19:32:13 UTC (rev 10128)
+++ trunk/Hibernate3/doc/reference/en/modules/tutorial.xml 2006-07-21 06:41:22 UTC (rev 10129)
@@ -931,7 +931,7 @@
</sect2>
- <sect2 id="tutorial-associations-working" revision="1">
+ <sect2 id="tutorial-associations-working" revision="2">
<title>Working the association</title>
<para>
@@ -1020,7 +1020,8 @@
Long eventId = mgr.createAndStoreEvent("My Event", new Date());
Long personId = mgr.createAndStorePerson("Foo", "Bar");
mgr.addPersonToEvent(personId, eventId);
- System.out.println("Added person " + personId + " to event " + eventId);]]></programlisting>
+ System.out.println("Added person " + personId + " to event " + eventId);
+}]]></programlisting>
<para>
This was an example of an association between two equally important classes, two entities.
|
|
From: <hib...@li...> - 2006-07-20 19:32:16
|
Author: scottmarlownovell
Date: 2006-07-20 15:32:13 -0400 (Thu, 20 Jul 2006)
New Revision: 10128
Modified:
trunk/Hibernate3/build.xml
Log:
Increase max memory to 256m for junitsingle to fix out of memory error.
Modified: trunk/Hibernate3/build.xml
===================================================================
--- trunk/Hibernate3/build.xml 2006-07-20 19:19:21 UTC (rev 10127)
+++ trunk/Hibernate3/build.xml 2006-07-20 19:32:13 UTC (rev 10128)
@@ -641,7 +641,7 @@
<target name="junitsingle" depends="cleantestdb,compiletest"
description="Run a single test suite (requires testname and jdbc.driver properties)">
<mkdir dir="${test.out.dir}"/>
- <junit printsummary="yes" fork="yes" haltonfailure="yes" dir="${basedir}">
+ <junit printsummary="yes" maxmemory="256M" fork="yes" haltonfailure="yes" dir="${basedir}">
<classpath>
<pathelement path="${etc.dir}"/> <!-- pick up property resources from the 'etc' directory first -->
<fileset dir="${lib.dir}">
|
|
From: <hib...@li...> - 2006-07-20 19:20:13
|
Author: ste...@jb...
Date: 2006-07-20 15:19:21 -0400 (Thu, 20 Jul 2006)
New Revision: 10127
Added:
trunk/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
trunk/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java
trunk/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java
Modified:
trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
Log:
HHH-1927 : persist() and merge() in same txn
Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractSaveEventListener.java 2006-07-20 19:19:21 UTC (rev 10127)
@@ -451,12 +451,29 @@
Object entity,
String entityName,
EntityEntry entry, //pass this as an argument only to avoid double looking
- SessionImplementor source
- ) {
-
- if ( entry!=null ) { // the object is persistent
-
- //the entity is associated with the session, so check its status
+ SessionImplementor source) {
+
+ if ( entry == null && performDeepStateChecking() ) {
+ // check to handle fringe case of merging the same "entity data" via
+ // a transient instance within the same transaction it was saved; i.e.:
+ // Session s = ...;
+ // s.beginTransaction();
+ // s.persist( new Entity( "someid" ) );
+ // s.merge( new Entity( "someid" ) );
+ // s.getTransaction().commit();
+ EntityPersister persister = source.getEntityPersister( entityName, entity );
+ Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+ if ( id != null ) {
+ EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+ entry = source.getPersistenceContext().getEntry(
+ source.getPersistenceContext().getEntity( key )
+ );
+ }
+ }
+
+ if ( entry != null ) {
+ // the object is persistent as it has an entry associated with the
+ // session; so check its status
if ( entry.getStatus() != Status.DELETED ) {
// do nothing for persistent instances
if ( log.isTraceEnabled() ) {
@@ -479,11 +496,10 @@
}
}
- else { // the object is transient or detached
-
- //the entity is not associated with the session, so
- //try interceptor and unsaved-value
-
+ else {
+ // the entity is not associated with the session, so the various
+ // unsaved-value algorithms to determine whether it is transient
+ // or detached
if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
if ( log.isTraceEnabled() ) {
log.trace(
@@ -514,4 +530,7 @@
return null;
}
+ protected boolean performDeepStateChecking() {
+ return false;
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/src/org/hibernate/event/def/DefaultMergeEventListener.java 2006-07-20 19:19:21 UTC (rev 10127)
@@ -116,7 +116,11 @@
}
}
-
+
+ protected boolean performDeepStateChecking() {
+ return true;
+ }
+
protected void entityIsPersistent(MergeEvent event, Map copyCache) {
log.trace("ignoring persistent instance");
Modified: trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-07-20 19:19:21 UTC (rev 10127)
@@ -2,6 +2,7 @@
package org.hibernate.test.ops;
import java.util.ArrayList;
+import java.util.Date;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -9,6 +10,7 @@
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.NonUniqueObjectException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Projections;
@@ -22,7 +24,59 @@
public MergeTest(String str) {
super(str);
}
-
+
+ public void testPersistThenMergeInSameTxnWithVersion() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ VersionedEntity entity = new VersionedEntity( "test", "test" );
+ s.persist( entity );
+ s.merge( new VersionedEntity( "test", "test-2" ) );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( entity );
+ tx.commit();
+ s.close();
+ }
+
+ public void testPersistThenMergeInSameTxnWithTimestamp() {
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ TimestampedEntity entity = new TimestampedEntity( "test", "test" );
+ s.persist( entity );
+ s.merge( new TimestampedEntity( "test", "test-2" ) );
+
+ try {
+ // control operation...
+ s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
+ fail( "saveOrUpdate() should fail here" );
+ }
+ catch( NonUniqueObjectException expected ) {
+ // expected behavior
+ }
+
+ tx.commit();
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( entity );
+ tx.commit();
+ s.close();
+ }
+
public void testMergeDeepTree() {
clearCounts();
@@ -330,7 +384,7 @@
}
protected String[] getMappings() {
- return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml" };
+ return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml", "ops/OptLockEntity.hbm.xml" };
}
public static Test suite() {
Added: trunk/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-07-20 19:19:21 UTC (rev 10127)
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+-->
+
+<hibernate-mapping package="org.hibernate.test.ops">
+
+ <class name="VersionedEntity" table="V_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <version name="version" column="VERS" type="long" />
+ <property name="name" column="NAME" type="string" />
+ </class>
+
+ <class name="TimestampedEntity" table="T_ENTITY">
+ <id name="id" column="ID" type="string">
+ <generator class="assigned"/>
+ </id>
+ <timestamp name="timestamp" column="TS" />
+ <property name="name" column="NAME" type="string" />
+ </class>
+
+</hibernate-mapping>
+
Added: trunk/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/TimestampedEntity.java 2006-07-20 19:19:21 UTC (rev 10127)
@@ -0,0 +1,47 @@
+package org.hibernate.test.ops;
+
+import java.util.Date;
+
+/**
+ * todo: describe TimestampedEntity
+ *
+ * @author Steve Ebersole
+ */
+public class TimestampedEntity {
+ private String id;
+ private String name;
+ private Date timestamp;
+
+ public TimestampedEntity() {
+ }
+
+ public TimestampedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+}
+
Added: trunk/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java 2006-07-20 17:27:30 UTC (rev 10126)
+++ trunk/Hibernate3/test/org/hibernate/test/ops/VersionedEntity.java 2006-07-20 19:19:21 UTC (rev 10127)
@@ -0,0 +1,44 @@
+package org.hibernate.test.ops;
+
+/**
+ * todo: describe VersionedEntity
+ *
+ * @author Steve Ebersole
+ */
+public class VersionedEntity {
+ private String id;
+ private String name;
+ private long version;
+
+ public VersionedEntity() {
+ }
+
+ public VersionedEntity(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+}
|
|
From: <hib...@li...> - 2006-07-20 17:27:33
|
Author: scottmarlownovell
Date: 2006-07-20 13:27:30 -0400 (Thu, 20 Jul 2006)
New Revision: 10126
Modified:
trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
Log:
Fix for HHH-1293. Switched to using InvocationHandler.
Modified: trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-07-19 14:11:50 UTC (rev 10125)
+++ trunk/Hibernate3/src/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java 2006-07-20 17:27:30 UTC (rev 10126)
@@ -4,16 +4,19 @@
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Factory;
-import net.sf.cglib.proxy.MethodInterceptor;
-import net.sf.cglib.proxy.MethodProxy;
+import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.NoOp;
import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
import org.hibernate.proxy.pojo.BasicLazyInitializer;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.engine.SessionImplementor;
@@ -25,11 +28,8 @@
/**
* A <tt>LazyInitializer</tt> implemented using the CGLIB bytecode generation library
*/
-public final class CGLIBLazyInitializer extends BasicLazyInitializer implements MethodInterceptor {
+public final class CGLIBLazyInitializer extends BasicLazyInitializer implements InvocationHandler {
-
- private static final Class[] CALLBACK_TYPES = new Class[]{ MethodInterceptor.class,NoOp.class };
-
private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
public int accept(Method method) {
if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
@@ -49,7 +49,7 @@
final Method setIdentifierMethod, AbstractComponentType componentIdType,
final Serializable id, final SessionImplementor session) throws HibernateException {
// note: interfaces is assumed to already contain HibernateProxy.class
-
+
try {
final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
entityName,
@@ -59,16 +59,13 @@
getIdentifierMethod,
setIdentifierMethod,
componentIdType,
- session
+ session
);
-
- final HibernateProxy proxy = (HibernateProxy) Enhancer.create(
- interfaces.length == 1 ? persistentClass : null,
- interfaces,
- FINALIZE_FILTER,
- new Callback[]{ instance, NoOp.INSTANCE }
- );
-
+
+ final HibernateProxy proxy;
+ Class factory = getProxyFactory(persistentClass, interfaces);
+ Enhancer.registerCallbacks(factory, new Callback[]{ instance, null });
+ proxy = (HibernateProxy)factory.newInstance();
instance.constructed = true;
return proxy;
}
@@ -84,7 +81,7 @@
final Method getIdentifierMethod, final Method setIdentifierMethod,
final AbstractComponentType componentIdType, final Serializable id,
final SessionImplementor session) throws HibernateException {
-
+
final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
entityName,
persistentClass,
@@ -93,17 +90,17 @@
getIdentifierMethod,
setIdentifierMethod,
componentIdType,
- session
+ session
);
-
+
final HibernateProxy proxy;
try {
- proxy = (HibernateProxy) factory.newInstance();
+ Enhancer.registerCallbacks(factory, new Callback[]{ instance, null });
+ proxy = (HibernateProxy)factory.newInstance();
}
catch (Exception e) {
throw new HibernateException( "CGLIB Enhancement failed: " + persistentClass.getName(), e );
}
- ( (Factory) proxy ).setCallback( 0, instance );
instance.constructed = true;
return proxy;
@@ -111,28 +108,17 @@
public static Class getProxyFactory(Class persistentClass, Class[] interfaces)
throws HibernateException {
- // note: interfaces is assumed to already contain HibernateProxy.class
-
- try {
-
- Enhancer en = new Enhancer();
- en.setUseCache( false );
- en.setInterceptDuringConstruction( false );
-
- en.setCallbackTypes( CALLBACK_TYPES );
- en.setCallbackFilter( FINALIZE_FILTER );
-
- en.setSuperclass( interfaces.length == 1 ? persistentClass : null );
- en.setInterfaces( interfaces );
-
- return en.createClass();
-
- }
- catch (Throwable t) {
- LogFactory.getLog( BasicLazyInitializer.class )
- .error( "CGLIB Enhancement failed: " + persistentClass.getName(), t );
- throw new HibernateException( "CGLIB Enhancement failed: " + persistentClass.getName(), t );
- }
+ Enhancer e = new Enhancer();
+ e.setSuperclass( interfaces.length == 1 ? persistentClass : null );
+ e.setInterfaces(interfaces);
+ e.setCallbackTypes(new Class[]{
+ InvocationHandler.class,
+ NoOp.class,
+ });
+ e.setCallbackFilter(FINALIZE_FILTER);
+ e.setUseFactory(false);
+ e.setInterceptDuringConstruction( false );
+ return e.createClass();
}
private CGLIBLazyInitializer(final String entityName, final Class persistentClass,
@@ -146,48 +132,80 @@
getIdentifierMethod,
setIdentifierMethod,
componentIdType,
- session
+ session
);
this.interfaces = interfaces;
}
- public Object intercept(final Object proxy, final Method method, final Object[] args,
- final MethodProxy methodProxy) throws Throwable {
+ private static boolean isCastable(Class caster, Class castee) {
+ if ( castee.equals( caster ) ) {
+ return true;
+ }
+ List list = addCheckingTypes( caster, new ArrayList() );
+ for ( Iterator iter = list.iterator(); iter.hasNext(); ) {
+ Class cl = ( Class ) iter.next();
+ if ( castee.equals( cl ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static List addCheckingTypes(final Class type, final List list) {
+ Class superclass = type.getSuperclass();
+ if ( superclass != null ) {
+ list.add( superclass );
+ addCheckingTypes( superclass, list );
+ }
+ Class[] interfaces = type.getInterfaces();
+ for ( int i = 0; i < interfaces.length; ++i ) {
+ list.add( interfaces[i] );
+ addCheckingTypes( interfaces[i], list );
+ }
+ return list;
+ }
+
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if ( constructed ) {
-
Object result = invoke( method, args, proxy );
if ( result == INVOKE_IMPLEMENTATION ) {
Object target = getImplementation();
final Object returnValue;
- if ( ReflectHelper.isPublic( persistentClass, method ) ) {
- returnValue = methodProxy.invoke( target, args );
- }
- else {
- if ( !method.isAccessible() ) method.setAccessible( true );
- try {
+ try {
+ if ( ReflectHelper.isPublic( persistentClass, method ) ) {
+ if ( !isCastable(
+ target.getClass(), method
+ .getDeclaringClass()
+ ) ) {
+ throw new ClassCastException(
+ target.getClass()
+ .getName()
+ );
+ }
returnValue = method.invoke( target, args );
}
- catch (InvocationTargetException ite) {
- throw ite.getTargetException();
+ else {
+ if ( !method.isAccessible() ) method.setAccessible( true );
+ returnValue = method.invoke( target, args );
}
+ return returnValue == target ? proxy : returnValue;
}
- return returnValue == target ? proxy : returnValue;
+ catch (InvocationTargetException ite) {
+ throw ite.getTargetException();
+ }
}
else {
return result;
}
-
}
else {
-
// while constructor is running
if ( method.getName().equals( "getHibernateLazyInitializer" ) ) {
return this;
}
else {
- return methodProxy.invokeSuper( proxy, args );
+ throw new LazyInitializationException("unexpected case hit, method=" + method.getName());
}
-
}
}
|
|
From: <hib...@li...> - 2006-07-19 14:11:55
|
Author: ste...@jb... Date: 2006-07-19 10:11:50 -0400 (Wed, 19 Jul 2006) New Revision: 10125 Added: branches/Branch_3_2/Hibernate3/ Log: branched 3.2 Copied: branches/Branch_3_2/Hibernate3 (from rev 10124, trunk/Hibernate3) |
|
From: <hib...@li...> - 2006-07-19 14:10:30
|
Author: ste...@jb... Date: 2006-07-19 10:10:21 -0400 (Wed, 19 Jul 2006) New Revision: 10124 Added: branches/Branch_3_2/ Log: created 3.2 branch directory |
|
From: <hib...@li...> - 2006-07-16 09:19:54
|
Author: max...@jb... Date: 2006-07-16 05:19:49 -0400 (Sun, 16 Jul 2006) New Revision: 10123 Modified: trunk/HibernateExt/build.bat Log: Modified: trunk/HibernateExt/build.bat =================================================================== (Binary files differ) |
|
From: <hib...@li...> - 2006-07-14 09:42:43
|
Author: max...@jb...
Date: 2006-07-14 05:42:39 -0400 (Fri, 14 Jul 2006)
New Revision: 10122
Modified:
trunk/Hibernate3/test/org/hibernate/test/TestCase.java
Log:
make the nightly build only fail if something unexpected occurs.
Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-07-14 03:52:37 UTC (rev 10121)
+++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-07-14 09:42:39 UTC (rev 10122)
@@ -3,7 +3,6 @@
import java.sql.Blob;
import java.sql.Clob;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -379,4 +378,27 @@
protected SessionFactoryImplementor sfi() {
return ( SessionFactoryImplementor ) getSessions();
}
+
+ public void runBare() throws Throwable {
+ assertNotNull(getName());
+ if(Boolean.getBoolean( "hibernate.test.validatefailureexpected" )) {
+ if(getName().endsWith( "FailureExpected" ) ) {
+ Throwable t = null;
+ try {
+ super.runBare();
+ } catch(Throwable afe) {
+ t = afe;
+ }
+ if(t==null) {
+ fail("Test where marked as FailureExpected, but did not fail!");
+ } else {
+ reportSkip( "ignoring *FailuredExpected methods", "Failed with: " + t.toString() );
+ }
+ } else {
+ super.runBare();
+ }
+ } else {
+ super.runBare();
+ }
+ }
}
\ No newline at end of file
|
|
From: <hib...@li...> - 2006-07-14 03:52:56
|
Author: ste...@jb...
Date: 2006-07-13 23:52:37 -0400 (Thu, 13 Jul 2006)
New Revision: 10121
Modified:
trunk/Hibernate3/test/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java
Log:
oops
Modified: trunk/Hibernate3/test/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java 2006-07-14 01:55:32 UTC (rev 10120)
+++ trunk/Hibernate3/test/org/hibernate/test/dynamicentity/tuplizer/MyEntityTuplizer.java 2006-07-14 03:52:37 UTC (rev 10121)
@@ -1,7 +1,7 @@
package org.hibernate.test.dynamicentity.tuplizer;
-import org.hibernate.tuple.PojoEntityTuplizer;
-import org.hibernate.tuple.EntityMetamodel;
+import org.hibernate.tuple.entity.PojoEntityTuplizer;
+import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.tuple.Instantiator;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.proxy.ProxyFactory;
@@ -9,7 +9,7 @@
import org.hibernate.property.Setter;
/**
- * @author <a href="mailto:st...@hi...">Steve Ebersole </a>
+ * @author Steve Ebersole
*/
public class MyEntityTuplizer extends PojoEntityTuplizer {
|
|
From: <hib...@li...> - 2006-07-14 01:55:35
|
Author: ste...@jb...
Date: 2006-07-13 21:55:32 -0400 (Thu, 13 Jul 2006)
New Revision: 10120
Added:
trunk/Hibernate3/test/org/hibernate/test/tm/DummyJTAStyleTransationFactory.java
Log:
oops
Added: trunk/Hibernate3/test/org/hibernate/test/tm/DummyJTAStyleTransationFactory.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/tm/DummyJTAStyleTransationFactory.java 2006-07-14 00:09:19 UTC (rev 10119)
+++ trunk/Hibernate3/test/org/hibernate/test/tm/DummyJTAStyleTransationFactory.java 2006-07-14 01:55:32 UTC (rev 10120)
@@ -0,0 +1,138 @@
+package org.hibernate.test.tm;
+
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.HibernateException;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.JTAHelper;
+import org.hibernate.jdbc.JDBCContext;
+
+import javax.transaction.SystemException;
+import javax.transaction.Synchronization;
+import java.util.Properties;
+
+/**
+ * todo: describe DummyJTAStyleTransationFactory
+ *
+ * @author Steve Ebersole
+ */
+public class DummyJTAStyleTransationFactory implements TransactionFactory {
+ public Transaction createTransaction(
+ JDBCContext jdbcContext,
+ Context context) throws HibernateException {
+ return new DummyTransactionAdapter();
+ }
+
+ public void configure(Properties props) throws HibernateException {
+ }
+
+ public ConnectionReleaseMode getDefaultReleaseMode() {
+ return ConnectionReleaseMode.AFTER_STATEMENT;
+ }
+
+ public boolean isTransactionManagerRequired() {
+ return true;
+ }
+
+ public boolean areCallbacksLocalToHibernateTransactions() {
+ return false;
+ }
+
+ public boolean isTransactionInProgress(
+ JDBCContext jdbcContext,
+ Context transactionContext,
+ Transaction transaction) {
+ try {
+ return JTAHelper.isTransactionInProgress( DummyTransactionManager.INSTANCE.getCurrent() )
+ && ! JTAHelper.isMarkedForRollback( DummyTransactionManager.INSTANCE.getCurrent() );
+ }
+ catch( SystemException e ) {
+ throw new HibernateException( e );
+ }
+ }
+
+ private static class DummyTransactionAdapter implements Transaction {
+
+ private boolean started;
+ private boolean committed;
+ private boolean rolledback;
+
+ public void begin() throws HibernateException {
+ started = true;
+ committed = false;
+ rolledback = false;
+ try {
+ DummyTransactionManager.INSTANCE.begin();
+ }
+ catch( Throwable t ) {
+ throw new HibernateException( "error on begin()", t );
+ }
+ }
+
+ public void commit() throws HibernateException {
+ if ( !started ) {
+ throw new HibernateException( "not yet started!" );
+ }
+ started = false;
+ rolledback = false;
+ committed = false;
+ try {
+ DummyTransactionManager.INSTANCE.commit();
+ committed = true;
+ }
+ catch( Throwable t ) {
+ throw new HibernateException( "error on commit()", t );
+ }
+ }
+
+ public void rollback() throws HibernateException {
+ if ( !started ) {
+ throw new HibernateException( "not yet started!" );
+ }
+ started = false;
+ rolledback = false;
+ committed = false;
+ try {
+ DummyTransactionManager.INSTANCE.rollback();
+ rolledback = true;
+ }
+ catch( Throwable t ) {
+ throw new HibernateException( "error on rollback()", t );
+ }
+ }
+
+ public boolean wasRolledBack() throws HibernateException {
+ return rolledback;
+ }
+
+ public boolean wasCommitted() throws HibernateException {
+ return committed;
+ }
+
+ public boolean isActive() throws HibernateException {
+ return started;
+ }
+
+ public void registerSynchronization(Synchronization synchronization) throws HibernateException {
+ try {
+ DummyTransactionManager.INSTANCE.getCurrent().registerSynchronization( synchronization );
+ }
+ catch( Throwable t ) {
+ throw new HibernateException( "error on registerSynchronization()", t );
+ }
+ }
+
+ public void setTimeout(int seconds) {
+ // ignore...
+ }
+ }
+
+ public static void setup(Configuration cfg) {
+ cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() );
+ cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() );
+ cfg.setProperty( Environment.TRANSACTION_STRATEGY, DummyJTAStyleTransationFactory.class.getName() );
+ cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" );
+ }
+}
|
|
From: <hib...@li...> - 2006-07-14 00:15:14
|
Author: ste...@jb...
Date: 2006-07-13 20:09:19 -0400 (Thu, 13 Jul 2006)
New Revision: 10119
Added:
trunk/Hibernate3/src/org/hibernate/tuple/EntityModeToTuplizerMapping.java
trunk/Hibernate3/src/org/hibernate/tuple/component/
trunk/Hibernate3/src/org/hibernate/tuple/component/AbstractComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java
trunk/Hibernate3/src/org/hibernate/tuple/component/ComponentMetamodel.java
trunk/Hibernate3/src/org/hibernate/tuple/component/ComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/component/Dom4jComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/component/PojoComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/
trunk/Hibernate3/src/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/EntityMetamodel.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/EntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/entity/PojoEntityTuplizer.java
Removed:
trunk/Hibernate3/src/org/hibernate/tuple/AbstractComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/AbstractEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/ComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/Dom4jComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/Dom4jEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/EntityMetamodel.java
trunk/Hibernate3/src/org/hibernate/tuple/EntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/PojoComponentTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/PojoEntityTuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/TuplizerLookup.java
Modified:
trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
trunk/Hibernate3/src/org/hibernate/mapping/Component.java
trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java
trunk/Hibernate3/src/org/hibernate/mapping/Subclass.java
trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
trunk/Hibernate3/src/org/hibernate/tuple/PropertyFactory.java
trunk/Hibernate3/src/org/hibernate/tuple/StandardProperty.java
trunk/Hibernate3/src/org/hibernate/tuple/Tuplizer.java
trunk/Hibernate3/src/org/hibernate/tuple/VersionProperty.java
trunk/Hibernate3/src/org/hibernate/type/ComponentType.java
trunk/Hibernate3/src/org/hibernate/type/EmbeddedComponentType.java
Log:
HHH-1907 : initial work
Modified: trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/cfg/HbmBinder.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1755,11 +1755,20 @@
}
- public static void bindComponent(Element node, Component component, String ownerClassName,
- String parentProperty, String path, boolean isNullable, boolean isEmbedded,
- Mappings mappings, java.util.Map inheritedMetas, boolean isIdentifierMapper) throws MappingException {
+ public static void bindComponent(
+ Element node,
+ Component component,
+ String ownerClassName,
+ String parentProperty,
+ String path,
+ boolean isNullable,
+ boolean isEmbedded,
+ Mappings mappings,
+ java.util.Map inheritedMetas,
+ boolean isIdentifierMapper) throws MappingException {
component.setEmbedded( isEmbedded );
+ component.setRoleName( path );
component.setMetaAttributes( getMetas( node, inheritedMetas ) );
Modified: trunk/Hibernate3/src/org/hibernate/mapping/Component.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/mapping/Component.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/mapping/Component.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -7,10 +7,8 @@
import java.util.Map;
import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.tuple.TuplizerLookup;
+import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.type.ComponentType;
import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.Type;
@@ -33,9 +31,30 @@
private Map metaAttributes;
private String nodeName;
private boolean isKey;
+ private String roleName;
private java.util.Map tuplizerImpls;
+ public Component(PersistentClass owner) throws MappingException {
+ super( owner.getTable() );
+ this.owner = owner;
+ }
+
+ public Component(Component component) throws MappingException {
+ super( component.getTable() );
+ this.owner = component.getOwner();
+ }
+
+ public Component(Join join) throws MappingException {
+ super( join.getTable() );
+ this.owner = join.getPersistentClass();
+ }
+
+ public Component(Collection collection) throws MappingException {
+ super( collection.getCollectionTable() );
+ this.owner = collection.getOwner();
+ }
+
public int getPropertySpan() {
return properties.size();
}
@@ -67,26 +86,6 @@
return new JoinedIterator(iters);
}
- public Component(PersistentClass owner) throws MappingException {
- super( owner.getTable() );
- this.owner = owner;
- }
-
- public Component(Component component) throws MappingException {
- super( component.getTable() );
- this.owner = component.getOwner();
- }
-
- public Component(Join join) throws MappingException {
- super( join.getTable() );
- this.owner = join.getPersistentClass();
- }
-
- public Component(Collection collection) throws MappingException {
- super( collection.getCollectionTable() );
- this.owner = collection.getOwner();
- }
-
public void setTypeByReflection(String propertyClass, String propertyName) {}
public boolean isEmbedded() {
@@ -149,49 +148,14 @@
}
private Type buildType() {
- final int span = getPropertySpan();
- String[] names = new String[span];
- org.hibernate.type.Type[] types = new org.hibernate.type.Type[span];
- boolean[] nullabilities = new boolean[span];
- CascadeStyle[] cascade = new CascadeStyle[span];
- FetchMode[] joinedFetch = new FetchMode[span];
- Iterator props = getPropertyIterator();
- int j=0;
- while ( props.hasNext() ) {
- Property prop = (Property) props.next();
- names[j] = prop.getName();
- types[j] = prop.getType();
- cascade[j] = prop.getCascadeStyle();
- joinedFetch[j] = prop.getValue().getFetchMode();
- nullabilities[j] = prop.isNullable();
- j++;
- }
-
- TuplizerLookup tuplizers = TuplizerLookup.create(this);
-
+ // TODO : temporary initial step towards HHH-1907
+ ComponentMetamodel metamodel = new ComponentMetamodel( this );
if ( isEmbedded() ) {
- return new EmbeddedComponentType(
- names,
- types,
- nullabilities,
- joinedFetch,
- cascade,
- isKey,
- tuplizers
- );
+ return new EmbeddedComponentType( metamodel );
}
else {
- return new ComponentType(
- names,
- types,
- nullabilities,
- joinedFetch,
- cascade,
- isKey,
- tuplizers
- );
+ return new ComponentType( metamodel );
}
-
}
public void setTypeUsingReflection(String className, String propertyName)
@@ -271,10 +235,20 @@
}
public String getTuplizerImplClassName(EntityMode mode) {
- if ( tuplizerImpls == null ) return null;
+ // todo : remove this once ComponentMetamodel is complete and merged
+ if ( tuplizerImpls == null ) {
+ return null;
+ }
return ( String ) tuplizerImpls.get( mode );
}
+ public Map getTuplizerMap() {
+ if ( tuplizerImpls == null ) {
+ return null;
+ }
+ return java.util.Collections.unmodifiableMap( tuplizerImpls );
+ }
+
public Property getProperty(String propertyName) throws MappingException {
Iterator iter = getPropertyIterator();
while ( iter.hasNext() ) {
@@ -286,6 +260,14 @@
throw new MappingException("component property not found: " + propertyName);
}
+ public String getRoleName() {
+ return roleName;
+ }
+
+ public void setRoleName(String roleName) {
+ this.roleName = roleName;
+ }
+
public String toString() {
return getClass().getName() + '(' + properties.toString() + ')';
}
Modified: trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -2,12 +2,8 @@
package org.hibernate.mapping;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.*;
import java.util.Set;
-import java.util.StringTokenizer;
import org.hibernate.MappingException;
import org.hibernate.EntityMode;
@@ -712,7 +708,14 @@
if ( tuplizerImpls == null ) return null;
return ( String ) tuplizerImpls.get( mode );
}
-
+
+ public java.util.Map getTuplizerMap() {
+ if ( tuplizerImpls == null ) {
+ return null;
+ }
+ return java.util.Collections.unmodifiableMap( tuplizerImpls );
+ }
+
public boolean hasNaturalId() {
Iterator props = getRootClass().getPropertyIterator();
while ( props.hasNext() ) {
Modified: trunk/Hibernate3/src/org/hibernate/mapping/Subclass.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/mapping/Subclass.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/mapping/Subclass.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -151,7 +151,9 @@
}
public void createForeignKey() {
- if ( !isJoinedSubclass() ) throw new AssertionFailure("not a joined-subclass");
+ if ( !isJoinedSubclass() ) {
+ throw new AssertionFailure( "not a joined-subclass" );
+ }
getKey().createForeignKeyOfEntity( getSuperclass().getEntityName() );
}
@@ -226,6 +228,24 @@
return impl;
}
+ public Map getTuplizerMap() {
+ Map specificTuplizerDefs = super.getTuplizerMap();
+ Map superclassTuplizerDefs = getSuperclass().getTuplizerMap();
+ if ( specificTuplizerDefs == null && superclassTuplizerDefs == null ) {
+ return null;
+ }
+ else {
+ Map combined = new HashMap();
+ if ( superclassTuplizerDefs != null ) {
+ combined.putAll( superclassTuplizerDefs );
+ }
+ if ( specificTuplizerDefs != null ) {
+ combined.putAll( specificTuplizerDefs );
+ }
+ return java.util.Collections.unmodifiableMap( combined );
+ }
+ }
+
public Component getIdentifierMapper() {
return superclass.getIdentifierMapper();
}
Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -2,11 +2,9 @@
package org.hibernate.persister.entity;
import java.io.Serializable;
-import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.sql.Types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -73,8 +71,8 @@
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
import org.hibernate.sql.Update;
-import org.hibernate.tuple.EntityMetamodel;
-import org.hibernate.tuple.EntityTuplizer;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.tuple.Tuplizer;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.AssociationType;
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/AbstractComponentTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/AbstractComponentTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/AbstractComponentTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,102 +0,0 @@
-//$Id$
-package org.hibernate.tuple;
-
-import java.lang.reflect.Method;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-
-/**
- * @author Gavin King
- */
-public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
-
- protected final Getter[] getters;
- protected final Setter[] setters;
- protected final int propertySpan;
- protected final Instantiator instantiator;
- protected final boolean hasCustomAccessors;
-
- protected abstract Instantiator buildInstantiator(Component component);
- protected abstract Getter buildGetter(Component component, Property prop);
- protected abstract Setter buildSetter(Component component, Property prop);
-
- protected AbstractComponentTuplizer(Component component) {
- propertySpan = component.getPropertySpan();
- getters = new Getter[propertySpan];
- setters = new Setter[propertySpan];
-
- Iterator iter = component.getPropertyIterator();
- boolean foundCustomAccessor=false;
- int i=0;
- while ( iter.hasNext() ) {
- Property prop = (Property) iter.next();
- getters[i] = buildGetter(component, prop);
- setters[i] = buildSetter(component, prop);
- if ( !prop.isBasicPropertyAccessor() ) foundCustomAccessor = true;
- i++;
- }
- hasCustomAccessors = foundCustomAccessor;
-
- String[] getterNames = new String[propertySpan];
- String[] setterNames = new String[propertySpan];
- Class[] propTypes = new Class[propertySpan];
- for ( int j = 0; j < propertySpan; j++ ) {
- getterNames[j] = getters[j].getMethodName();
- setterNames[j] = setters[j].getMethodName();
- propTypes[j] = getters[j].getReturnType();
- }
- instantiator = buildInstantiator(component);
- }
-
- public Object getPropertyValue(Object component, int i) throws HibernateException {
- return getters[i].get( component );
- }
-
- public Object[] getPropertyValues(Object component) throws HibernateException {
- Object[] values = new Object[propertySpan];
- for ( int i = 0; i < propertySpan; i++ ) {
- values[i] = getPropertyValue( component, i );
- }
- return values;
- }
-
- public boolean isInstance(Object object) {
- return instantiator.isInstance(object);
- }
-
- public void setPropertyValues(Object component, Object[] values) throws HibernateException {
- for ( int i = 0; i < propertySpan; i++ ) {
- setters[i].set( component, values[i], null );
- }
- }
-
- /**
- * This method does not populate the component parent
- */
- public Object instantiate() throws HibernateException {
- return instantiator.instantiate();
- }
-
- public Object getParent(Object component) {
- return null;
- }
-
- public boolean hasParentProperty() {
- return false;
- }
-
- public boolean isMethodOf(Method method) {
- return false;
- }
-
- public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
- throw new UnsupportedOperationException();
- }
-
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/AbstractEntityTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/AbstractEntityTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/AbstractEntityTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,403 +0,0 @@
-// $Id$
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.Assigned;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.ComponentType;
-
-
-/**
- * Support base class for EntityTuplizer implementations.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractEntityTuplizer implements EntityTuplizer {
-
- //TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
-
- private final EntityMetamodel entityMetamodel;
-
- private final Getter idGetter;
- private final Setter idSetter;
-
- protected final Getter[] getters;
- protected final Setter[] setters;
- protected final int propertySpan;
- protected final boolean hasCustomAccessors;
- private final Instantiator instantiator;
- private final ProxyFactory proxyFactory;
- private final AbstractComponentType identifierMapperType;
-
-
- /**
- * Return the entity-mode handled by this tuplizer instance.
- *
- * @return The entity-mode
- */
- protected abstract EntityMode getEntityMode();
-
- /**
- * Build an appropriate Getter for the given property.
- *
- * @param mappedProperty The property to be accessed via the built Getter.
- * @param mappedEntity The entity information regarding the mapped entity owning this property.
- * @return An appropriate Getter instance.
- */
- protected abstract Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity);
-
- /**
- * Build an appropriate Setter for the given property.
- *
- * @param mappedProperty The property to be accessed via the built Setter.
- * @param mappedEntity The entity information regarding the mapped entity owning this property.
- * @return An appropriate Setter instance.
- */
- protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity);
-
- /**
- * Build an appropriate Instantiator for the given mapped entity.
- *
- * @param mappingInfo The mapping information regarding the mapped entity.
- * @return An appropriate Instantiator instance.
- */
- protected abstract Instantiator buildInstantiator(PersistentClass mappingInfo);
-
- /**
- * Build an appropriate ProxyFactory for the given mapped entity.
- *
- * @param mappingInfo The mapping information regarding the mapped entity.
- * @param idGetter The constructed Getter relating to the entity's id property.
- * @param idSetter The constructed Setter relating to the entity's id property.
- * @return An appropriate ProxyFactory instance.
- */
- protected abstract ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter);
-
- /**
- * Constructs a new AbstractEntityTuplizer instance.
- *
- * @param entityMetamodel The "interpreted" information relating to the mapped entity.
- * @param mappingInfo The parsed "raw" mapping data relating to the given entity.
- */
- public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
- this.entityMetamodel = entityMetamodel;
-
- if ( !entityMetamodel.getIdentifierProperty().isVirtual() ) {
- idGetter = buildPropertyGetter( mappingInfo.getIdentifierProperty(), mappingInfo );
- idSetter = buildPropertySetter( mappingInfo.getIdentifierProperty(), mappingInfo );
- }
- else {
- idGetter = null;
- idSetter = null;
- }
-
- propertySpan = entityMetamodel.getPropertySpan();
-
- getters = new Getter[propertySpan];
- setters = new Setter[propertySpan];
-
- Iterator iter = mappingInfo.getPropertyClosureIterator();
- boolean foundCustomAccessor=false;
- int i=0;
- while ( iter.hasNext() ) {
- //TODO: redesign how PropertyAccessors are acquired...
- Property property = (Property) iter.next();
- getters[i] = buildPropertyGetter(property, mappingInfo);
- setters[i] = buildPropertySetter(property, mappingInfo);
- if ( !property.isBasicPropertyAccessor() ) foundCustomAccessor = true;
- i++;
- }
- hasCustomAccessors = foundCustomAccessor;
-
- instantiator = buildInstantiator( mappingInfo );
-
- if ( entityMetamodel.isLazy() ) {
- proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
- }
- else {
- proxyFactory = null;
- }
-
- Component mapper = mappingInfo.getIdentifierMapper();
- identifierMapperType = mapper==null ? null : (AbstractComponentType) mapper.getType();
- }
-
- /** Retreives the defined entity-name for the tuplized entity.
- *
- * @return The entity-name.
- */
- protected String getEntityName() {
- return entityMetamodel.getName();
- }
-
- /**
- * Retreives the defined entity-names for any subclasses defined for this
- * entity.
- *
- * @return Any subclass entity-names.
- */
- protected Set getSubclassEntityNames() {
- return entityMetamodel.getSubclassEntityNames();
- }
-
- public Serializable getIdentifier(Object entity) throws HibernateException {
- final Object id;
- if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
- id = entity;
- }
- else {
- if ( idGetter == null ) {
- if (identifierMapperType==null) {
- throw new HibernateException( "The class has no identifier property: " + getEntityName() );
- }
- else {
- ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
- id = copier.instantiate( getEntityMode() );
- copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() );
- }
- }
- else {
- id = idGetter.get( entity );
- }
- }
-
- try {
- return (Serializable) id;
- }
- catch ( ClassCastException cce ) {
- StringBuffer msg = new StringBuffer( "Identifier classes must be serializable. " );
- if ( id != null ) {
- msg.append( id.getClass().getName() + " is not serializable. " );
- }
- if ( cce.getMessage() != null ) {
- msg.append( cce.getMessage() );
- }
- throw new ClassCastException( msg.toString() );
- }
- }
-
-
- public void setIdentifier(Object entity, Serializable id) throws HibernateException {
- if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
- if ( entity != id ) {
- AbstractComponentType copier = (AbstractComponentType) entityMetamodel.getIdentifierProperty().getType();
- copier.setPropertyValues( entity, copier.getPropertyValues( id, getEntityMode() ), getEntityMode() );
- }
- }
- else if ( idSetter != null ) {
- idSetter.set( entity, id, getFactory() );
- }
- }
-
- public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion) {
- if ( entityMetamodel.getIdentifierProperty().getIdentifierGenerator() instanceof Assigned ) {
- //return currentId;
- }
- else {
- //reset the id
- Serializable result = entityMetamodel.getIdentifierProperty()
- .getUnsavedValue()
- .getDefaultValue( currentId );
- setIdentifier( entity, result );
- //reset the version
- VersionProperty versionProperty = entityMetamodel.getVersionProperty();
- if ( entityMetamodel.isVersioned() ) {
- setPropertyValue(
- entity,
- entityMetamodel.getVersionPropertyIndex(),
- versionProperty.getUnsavedValue().getDefaultValue( currentVersion )
- );
- }
- //return the id, so we can use it to reset the proxy id
- //return result;
- }
- }
-
- public Object getVersion(Object entity) throws HibernateException {
- if ( !entityMetamodel.isVersioned() ) return null;
- return getters[ entityMetamodel.getVersionPropertyIndex() ].get( entity );
- }
-
- protected boolean shouldGetAllProperties(Object entity) {
- return !hasUninitializedLazyProperties( entity );
- }
-
- public Object[] getPropertyValues(Object entity) throws HibernateException {
- boolean getAll = shouldGetAllProperties( entity );
- final int span = entityMetamodel.getPropertySpan();
- final Object[] result = new Object[span];
-
- for ( int j = 0; j < span; j++ ) {
- StandardProperty property = entityMetamodel.getProperties()[j];
- if ( getAll || !property.isLazy() ) {
- result[j] = getters[j].get( entity );
- }
- else {
- result[j] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
- }
- }
- return result;
- }
-
- public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session)
- throws HibernateException {
- final int span = entityMetamodel.getPropertySpan();
- final Object[] result = new Object[span];
-
- for ( int j = 0; j < span; j++ ) {
- result[j] = getters[j].getForInsert( entity, mergeMap, session );
- }
- return result;
- }
-
- public Object getPropertyValue(Object entity, int i) throws HibernateException {
- return getters[i].get( entity );
- }
-
- public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException {
-
- int loc = propertyPath.indexOf('.');
- String basePropertyName = loc>0 ?
- propertyPath.substring(0, loc) : propertyPath;
-
- int index = entityMetamodel.getPropertyIndex( basePropertyName );
- Object baseValue = getPropertyValue( entity, index );
- if ( loc>0 ) {
- ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index];
- return getComponentValue( type, baseValue, propertyPath.substring(loc+1) );
- }
- else {
- return baseValue;
- }
- }
-
- /**
- * Extract a component property value.
- *
- * @param type The component property types.
- * @param component The component instance itself.
- * @param propertyPath The property path for the property to be extracted.
- * @return The property value extracted.
- */
- protected Object getComponentValue(ComponentType type, Object component, String propertyPath) {
-
- int loc = propertyPath.indexOf('.');
- String basePropertyName = loc>0 ?
- propertyPath.substring(0, loc) : propertyPath;
-
- String[] propertyNames = type.getPropertyNames();
- int index=0;
- for ( ; index<propertyNames.length; index++ ) {
- if ( basePropertyName.equals( propertyNames[index] ) ) break;
- }
- if (index==propertyNames.length) {
- throw new MappingException( "component property not found: " + basePropertyName );
- }
-
- Object baseValue = type.getPropertyValue( component, index, getEntityMode() );
-
- if ( loc>0 ) {
- ComponentType subtype = (ComponentType) type.getSubtypes()[index];
- return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) );
- }
- else {
- return baseValue;
- }
-
- }
-
- public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
- boolean setAll = !entityMetamodel.hasLazyProperties();
-
- for ( int j = 0; j < entityMetamodel.getPropertySpan(); j++ ) {
- if ( setAll || values[j] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
- setters[j].set( entity, values[j], getFactory() );
- }
- }
- }
-
- public void setPropertyValue(Object entity, int i, Object value) throws HibernateException {
- setters[i].set( entity, value, getFactory() );
- }
-
- public void setPropertyValue(Object entity, String propertyName, Object value) throws HibernateException {
- setters[ entityMetamodel.getPropertyIndex( propertyName ) ].set( entity, value, getFactory() );
- }
-
- public final Object instantiate(Serializable id) throws HibernateException {
- Object result = getInstantiator().instantiate( id );
- if ( id != null ) {
- setIdentifier( result, id );
- }
- return result;
- }
-
- public final Object instantiate() throws HibernateException {
- return instantiate( null );
- }
-
- public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {}
-
- public boolean hasUninitializedLazyProperties(Object entity) {
- // the default is to simply not lazy fetch properties for now...
- return false;
- }
-
- public final boolean isInstance(Object object) {
- return getInstantiator().isInstance( object );
- }
-
- public boolean hasProxy() {
- return entityMetamodel.isLazy();
- }
-
- public final Object createProxy(Serializable id, SessionImplementor session)
- throws HibernateException {
- return getProxyFactory().getProxy( id, session );
- }
-
- public boolean isLifecycleImplementor() {
- return false;
- }
-
- public boolean isValidatableImplementor() {
- return false;
- }
-
- protected final EntityMetamodel getEntityMetamodel() {
- return entityMetamodel;
- }
-
- protected final SessionFactoryImplementor getFactory() {
- return entityMetamodel.getSessionFactory();
- }
-
- protected final Instantiator getInstantiator() {
- return instantiator;
- }
-
- protected final ProxyFactory getProxyFactory() {
- return proxyFactory;
- }
-
- public String toString() {
- return getClass().getName() + '(' + getEntityMetamodel().getName() + ')';
- }
-
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/ComponentTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/ComponentTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/ComponentTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,51 +0,0 @@
-//$Id$
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Defines further responsibilities reagarding tuplization based on
- * a mapped components.
- * </p>
- * ComponentTuplizer implementations should have the following constructor signature:
- * (org.hibernate.mapping.Component)
- *
- * @author Gavin King
- */
-public interface ComponentTuplizer extends Tuplizer, Serializable {
- /**
- * Retreive the current value of the parent property.
- *
- * @param component The component instance from which to extract the parent
- * property value.
- * @return The current value of the parent property.
- */
- public Object getParent(Object component);
-
- /**
- * Set the value of the parent property.
- *
- * @param component The component instance on which to set the parent.
- * @param parent The parent to be set on the comonent.
- * @param factory The current session factory.
- */
- public void setParent(Object component, Object parent, SessionFactoryImplementor factory);
-
- /**
- * Does the component managed by this tuuplizer contain a parent property?
- *
- * @return True if the component does contain a parent property; false otherwise.
- */
- public boolean hasParentProperty();
-
- /**
- * Is the given method available via the managed component as a property getter?
- *
- * @param method The method which to check against the managed component.
- * @return True if the managed component is available from the managed component; else false.
- */
- public boolean isMethodOf(Method method);
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/Dom4jComponentTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/Dom4jComponentTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/Dom4jComponentTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,42 +0,0 @@
-//$Id$
-package org.hibernate.tuple;
-
-import org.dom4j.Element;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-
-/**
- * @author Gavin King
- */
-public class Dom4jComponentTuplizer extends AbstractComponentTuplizer {
-
- public Class getMappedClass() {
- return Element.class;
- }
-
- public Dom4jComponentTuplizer(Component component) {
- super(component);
- }
-
- protected Instantiator buildInstantiator(Component component) {
- return new Dom4jInstantiator( component );
- }
-
- private PropertyAccessor buildPropertyAccessor(Property property) {
- //TODO: currently we don't know a SessionFactory reference when building the Tuplizer
- // THIS IS A BUG (embedded-xml=false on component)
- return PropertyAccessorFactory.getDom4jPropertyAccessor( property.getNodeName(), property.getType(), null );
- }
-
- protected Getter buildGetter(Component component, Property prop) {
- return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
- }
- protected Setter buildSetter(Component component, Property prop) {
- return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
- }
-
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/Dom4jEntityTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/Dom4jEntityTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/Dom4jEntityTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,120 +0,0 @@
-// $Id$
-package org.hibernate.tuple;
-
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.dom4j.Dom4jProxyFactory;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.type.AbstractComponentType;
-import org.dom4j.Element;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Iterator;
-
-/**
- * Implementation of Dom4jEntityTuplizer.
- *
- * @author Steve Ebersole
- */
-public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
-
- static final Log log = LogFactory.getLog( Dom4jEntityTuplizer.class );
-
- private Set subclassNodeNames = new HashSet();
-
- Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
- super(entityMetamodel, mappedEntity);
- Iterator itr = mappedEntity.getSubclassClosureIterator();
- while( itr.hasNext() ) {
- final PersistentClass mapping = ( PersistentClass ) itr.next();
- subclassNodeNames.add( mapping.getNodeName() );
- }
- }
-
- public EntityMode getEntityMode() {
- return EntityMode.DOM4J;
- }
-
- private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
- if ( mappedProperty.isBackRef() ) {
- return mappedProperty.getPropertyAccessor(null);
- }
- else {
- return PropertyAccessorFactory.getDom4jPropertyAccessor(
- mappedProperty.getNodeName(),
- mappedProperty.getType(),
- getEntityMetamodel().getSessionFactory()
- );
- }
- }
-
- protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
- return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
- }
-
- protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
- return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
- }
-
- protected Instantiator buildInstantiator(PersistentClass persistentClass) {
- return new Dom4jInstantiator( persistentClass );
- }
-
- public Serializable getIdentifier(Object entityOrId) throws HibernateException {
- if (entityOrId instanceof Element) {
- return super.getIdentifier(entityOrId);
- }
- else {
- //it was not embedded, so the argument is just an id
- return (Serializable) entityOrId;
- }
- }
-
- protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
- HashSet proxyInterfaces = new HashSet();
- proxyInterfaces.add( HibernateProxy.class );
- proxyInterfaces.add( Element.class );
-
- ProxyFactory pf = new Dom4jProxyFactory();
- try {
- pf.postInstantiate(
- getEntityName(),
- Element.class,
- proxyInterfaces,
- null,
- null,
- mappingInfo.hasEmbeddedIdentifier() ?
- (AbstractComponentType) mappingInfo.getIdentifier().getType() :
- null
- );
- }
- catch ( HibernateException he ) {
- log.warn( "could not create proxy factory for:" + getEntityName(), he );
- pf = null;
- }
- return pf;
- }
-
- public Class getMappedClass() {
- return Element.class;
- }
-
- public Class getConcreteProxyClass() {
- return Element.class;
- }
-
- public boolean isInstrumented() {
- return false;
- }
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapComponentTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapComponentTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapComponentTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,42 +0,0 @@
-//$Id$
-package org.hibernate.tuple;
-
-import java.util.Map;
-
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-
-/**
- * @author Gavin King
- */
-public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer {
-
- public Class getMappedClass() {
- return Map.class;
- }
-
- protected Instantiator buildInstantiator(Component component) {
- return new DynamicMapInstantiator();
- }
-
- public DynamicMapComponentTuplizer(Component component) {
- super(component);
- }
-
- private PropertyAccessor buildPropertyAccessor(Property property) {
- return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
- }
-
- protected Getter buildGetter(Component component, Property prop) {
- return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
- }
-
- protected Setter buildSetter(Component component, Property prop) {
- return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
- }
-
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapEntityTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapEntityTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/DynamicMapEntityTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,89 +0,0 @@
-// $Id$
-package org.hibernate.tuple;
-
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.proxy.map.MapProxyFactory;
-import org.hibernate.proxy.ProxyFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Implementation of DynamicMapEntityTuplizer.
- *
- * @author Steve Ebersole
- */
-public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
-
- static final Log log = LogFactory.getLog( DynamicMapEntityTuplizer.class );
-
- DynamicMapEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
- super(entityMetamodel, mappedEntity);
- }
-
- public EntityMode getEntityMode() {
- return EntityMode.MAP;
- }
-
- private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
- if ( mappedProperty.isBackRef() ) {
- return mappedProperty.getPropertyAccessor(null);
- }
- else {
- return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
- }
- }
-
- protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
- return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
- }
-
- protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
- return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
- }
-
- protected Instantiator buildInstantiator(PersistentClass mappingInfo) {
- return new DynamicMapInstantiator( mappingInfo );
- }
-
- protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
-
- ProxyFactory pf = new MapProxyFactory();
- try {
- //TODO: design new lifecycle for ProxyFactory
- pf.postInstantiate(
- getEntityName(),
- null,
- null,
- null,
- null,
- null
- );
- }
- catch ( HibernateException he ) {
- log.warn( "could not create proxy factory for:" + getEntityName(), he );
- pf = null;
- }
- return pf;
- }
-
- public Class getMappedClass() {
- return Map.class;
- }
-
- public Class getConcreteProxyClass() {
- return Map.class;
- }
-
- public boolean isInstrumented() {
- return false;
- }
-}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/EntityMetamodel.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/EntityMetamodel.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/EntityMetamodel.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,481 +0,0 @@
-// $Id$
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.Versioning;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Centralizes metamodel information about an entity.
- *
- * @author Steve Ebersole
- */
-public class EntityMetamodel implements Serializable {
-
- private static final Log log = LogFactory.getLog(EntityMetamodel.class);
-
- private static final int NO_VERSION_INDX = -66;
-
- private final SessionFactoryImplementor sessionFactory;
-
- private final String name;
- private final String rootName;
- private final EntityType entityType;
-
- private final IdentifierProperty identifierProperty;
- private final boolean versioned;
-
- private final int propertySpan;
- private final int versionPropertyIndex;
- private final StandardProperty[] properties;
- // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- private final String[] propertyNames;
- private final Type[] propertyTypes;
- private final boolean[] propertyLaziness;
- private final boolean[] propertyUpdateability;
- private final boolean[] nonlazyPropertyUpdateability;
- private final boolean[] propertyCheckability;
- private final boolean[] propertyInsertability;
- private final boolean[] propertyInsertGeneration;
- private final boolean[] propertyUpdateGeneration;
- private final boolean[] propertyNullability;
- private final boolean[] propertyVersionability;
- private final CascadeStyle[] cascadeStyles;
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- private final Map propertyIndexes = new HashMap();
- private final boolean hasCollections;
- private final boolean hasMutableProperties;
- private final boolean hasLazyProperties;
-
- private final int[] naturalIdPropertyNumbers;
-
- private final boolean lazy;
- private final boolean hasCascades;
- private final boolean mutable;
- private final boolean isAbstract;
- private final boolean selectBeforeUpdate;
- private final boolean dynamicUpdate;
- private final boolean dynamicInsert;
- private final int optimisticLockMode;
-
- private final boolean polymorphic;
- private final String superclass; // superclass entity-name
- private final boolean explicitPolymorphism;
- private final boolean inherited;
- private final boolean hasSubclasses;
- private final Set subclassEntityNames = new HashSet();
-
- private final TuplizerLookup tuplizers;
-
- public EntityTuplizer getTuplizer(EntityMode entityMode) {
- return (EntityTuplizer) tuplizers.getTuplizer(entityMode);
- }
-
- public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
- return (EntityTuplizer) tuplizers.getTuplizerOrNull(entityMode);
- }
-
- public EntityMode guessEntityMode(Object object) {
- return tuplizers.guessEntityMode(object);
- }
-
- public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
- this.sessionFactory = sessionFactory;
-
- name = persistentClass.getEntityName();
- rootName = persistentClass.getRootClass().getEntityName();
- entityType = TypeFactory.manyToOne( name );
-
- identifierProperty = PropertyFactory.buildIdentifierProperty(
- persistentClass,
- sessionFactory.getIdentifierGenerator( rootName )
- );
-
- versioned = persistentClass.isVersioned();
-
- boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
- FieldInterceptionHelper.isInstrumented( persistentClass.getMappedClass() );
- boolean hasLazy = false;
-
- propertySpan = persistentClass.getPropertyClosureSpan();
- properties = new StandardProperty[propertySpan];
- List naturalIdNumbers = new ArrayList();
- // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- propertyNames = new String[propertySpan];
- propertyTypes = new Type[propertySpan];
- propertyUpdateability = new boolean[propertySpan];
- propertyInsertability = new boolean[propertySpan];
- propertyInsertGeneration = new boolean[propertySpan];
- propertyUpdateGeneration = new boolean[propertySpan];
- nonlazyPropertyUpdateability = new boolean[propertySpan];
- propertyCheckability = new boolean[propertySpan];
- propertyNullability = new boolean[propertySpan];
- propertyVersionability = new boolean[propertySpan];
- propertyLaziness = new boolean[propertySpan];
- cascadeStyles = new CascadeStyle[propertySpan];
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
- Iterator iter = persistentClass.getPropertyClosureIterator();
- int i = 0;
- int tempVersionProperty = NO_VERSION_INDX;
- boolean foundCascade = false;
- boolean foundCollection = false;
- boolean foundMutable = false;
-
- while ( iter.hasNext() ) {
- Property prop = ( Property ) iter.next();
-
- if ( prop == persistentClass.getVersion() ) {
- tempVersionProperty = i;
- properties[i] = PropertyFactory.buildVersionProperty( prop, lazyAvailable );
- }
- else {
- properties[i] = PropertyFactory.buildStandardProperty( prop, lazyAvailable );
- }
-
- if ( prop.isNaturalIdentifier() ) {
- naturalIdNumbers.add( new Integer(i) );
- }
-
- // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- boolean lazy = prop.isLazy() && lazyAvailable;
- if ( lazy ) hasLazy = true;
- propertyLaziness[i] = lazy;
-
- propertyNames[i] = properties[i].getName();
- propertyTypes[i] = properties[i].getType();
- propertyNullability[i] = properties[i].isNullable();
- propertyUpdateability[i] = properties[i].isUpdateable();
- propertyInsertability[i] = properties[i].isInsertable();
- propertyInsertGeneration[i] = properties[i].isInsertGenerated();
- propertyUpdateGeneration[i] = properties[i].isUpdateGenerated();
- propertyVersionability[i] = properties[i].isVersionable();
- nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
- propertyCheckability[i] = propertyUpdateability[i] ||
- ( propertyTypes[i].isAssociationType() && ( (AssociationType) propertyTypes[i] ).isAlwaysDirtyChecked() );
-
- cascadeStyles[i] = properties[i].getCascadeStyle();
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- if ( properties[i].isLazy() ) {
- hasLazy = true;
- }
-
- if ( properties[i].getCascadeStyle() != CascadeStyle.NONE ) {
- foundCascade = true;
- }
-
- if ( indicatesCollection( properties[i].getType() ) ) {
- foundCollection = true;
- }
-
- if ( propertyTypes[i].isMutable() && propertyCheckability[i] ) {
- foundMutable = true;
- }
-
- mapPropertyToIndex(prop, i);
- i++;
- }
-
- if (naturalIdNumbers.size()==0) {
- naturalIdPropertyNumbers = null;
- }
- else {
- naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
- }
-
- hasCascades = foundCascade;
- versionPropertyIndex = tempVersionProperty;
- hasLazyProperties = hasLazy;
- if (hasLazyProperties) log.info("lazy property fetching available for: " + name);
-
- lazy = persistentClass.isLazy() && (
- // TODO: this disables laziness even in non-pojo entity modes:
- !persistentClass.hasPojoRepresentation() ||
- !ReflectHelper.isFinalClass( persistentClass.getProxyInterface() )
- );
- mutable = persistentClass.isMutable();
- if ( persistentClass.isAbstract() == null ) {
- // legacy behavior (with no abstract attribute specified)
- isAbstract = persistentClass.hasPojoRepresentation() &&
- ReflectHelper.isAbstractClass( persistentClass.getMappedClass() );
- }
- else {
- isAbstract = persistentClass.isAbstract().booleanValue();
- if ( !isAbstract && persistentClass.hasPojoRepresentation() &&
- ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ) ) {
- log.warn( "entity [" + name + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names" );
- }
- }
- selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
- dynamicUpdate = persistentClass.useDynamicUpdate();
- dynamicInsert = persistentClass.useDynamicInsert();
-
- polymorphic = persistentClass.isPolymorphic();
- explicitPolymorphism = persistentClass.isExplicitPolymorphism();
- inherited = persistentClass.isInherited();
- superclass = inherited ?
- persistentClass.getSuperclass().getEntityName() :
- null;
- hasSubclasses = persistentClass.hasSubclasses();
-
- optimisticLockMode = persistentClass.getOptimisticLockMode();
- if ( optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION && !dynamicUpdate ) {
- throw new MappingException( "optimistic-lock setting requires dynamic-update=\"true\": " + name );
- }
-
- hasCollections = foundCollection;
- hasMutableProperties = foundMutable;
-
- tuplizers = TuplizerLookup.create(persistentClass, this);
-
- iter = persistentClass.getSubclassIterator();
- while ( iter.hasNext() ) {
- subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
- }
- subclassEntityNames.add( name );
-
- }
-
- private void mapPropertyToIndex(Property prop, int i) {
- propertyIndexes.put( prop.getName(), new Integer(i) );
- if ( prop.getValue() instanceof Component ) {
- Iterator iter = ( (Component) prop.getValue() ).getPropertyIterator();
- while ( iter.hasNext() ) {
- Property subprop = (Property) iter.next();
- propertyIndexes.put(
- prop.getName() + '.' + subprop.getName(),
- new Integer(i)
- );
- }
- }
- }
-
- public int[] getNaturalIdentifierProperties() {
- return naturalIdPropertyNumbers;
- }
-
- public boolean hasNaturalIdentifier() {
- return naturalIdPropertyNumbers!=null;
- }
-
- public Set getSubclassEntityNames() {
- return subclassEntityNames;
- }
-
- private boolean indicatesCollection(Type type) {
- if ( type.isCollectionType() ) {
- return true;
- }
- else if ( type.isComponentType() ) {
- Type[] subtypes = ( ( AbstractComponentType ) type ).getSubtypes();
- for ( int i = 0; i < subtypes.length; i++ ) {
- if ( indicatesCollection( subtypes[i] ) ) {
- return true;
- }
- }
- }
- return false;
- }
-
- public SessionFactoryImplementor getSessionFactory() {
- return sessionFactory;
- }
-
- public String getName() {
- return name;
- }
-
- public String getRootName() {
- return rootName;
- }
-
- public EntityType getEntityType() {
- return entityType;
- }
-
- public IdentifierProperty getIdentifierProperty() {
- return identifierProperty;
- }
-
- public int getPropertySpan() {
- return propertySpan;
- }
-
- public int getVersionPropertyIndex() {
- return versionPropertyIndex;
- }
-
- public VersionProperty getVersionProperty() {
- if ( NO_VERSION_INDX == versionPropertyIndex ) {
- return null;
- }
- else {
- return ( VersionProperty ) properties[ versionPropertyIndex ];
- }
- }
-
- public StandardProperty[] getProperties() {
- return properties;
- }
-
- public int getPropertyIndex(String propertyName) {
- Integer index = getPropertyIndexOrNull(propertyName);
- if ( index == null ) {
- throw new HibernateException("Unable to resolve property: " + propertyName);
- }
- return index.intValue();
- }
-
- public Integer getPropertyIndexOrNull(String propertyName) {
- return (Integer) propertyIndexes.get( propertyName );
- }
-
- public boolean hasCollections() {
- return hasCollections;
- }
-
- public boolean hasMutableProperties() {
- return hasMutableProperties;
- }
-
- public boolean hasLazyProperties() {
- return hasLazyProperties;
- }
-
- public boolean hasCascades() {
- return hasCascades;
- }
-
- public boolean isMutable() {
- return mutable;
- }
-
- public boolean isSelectBeforeUpdate() {
- return selectBeforeUpdate;
- }
-
- public boolean isDynamicUpdate() {
- return dynamicUpdate;
- }
-
- public boolean isDynamicInsert() {
- return dynamicInsert;
- }
-
- public int getOptimisticLockMode() {
- return optimisticLockMode;
- }
-
- public boolean isPolymorphic() {
- return polymorphic;
- }
-
- public String getSuperclass() {
- return superclass;
- }
-
- public boolean isExplicitPolymorphism() {
- return explicitPolymorphism;
- }
-
- public boolean isInherited() {
- return inherited;
- }
-
- public boolean hasSubclasses() {
- return hasSubclasses;
- }
-
- public boolean isLazy() {
- return lazy;
- }
-
- public boolean isVersioned() {
- return versioned;
- }
-
- public boolean isAbstract() {
- return isAbstract;
- }
-
- public String toString() {
- return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
- }
-
- // temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- public String[] getPropertyNames() {
- return propertyNames;
- }
-
- public Type[] getPropertyTypes() {
- return propertyTypes;
- }
-
- public boolean[] getPropertyLaziness() {
- return propertyLaziness;
- }
-
- public boolean[] getPropertyUpdateability() {
- return propertyUpdateability;
- }
-
- public boolean[] getPropertyCheckability() {
- return propertyCheckability;
- }
-
- public boolean[] getNonlazyPropertyUpdateability() {
- return nonlazyPropertyUpdateability;
- }
-
- public boolean[] getPropertyInsertability() {
- return propertyInsertability;
- }
-
- public boolean[] getPropertyInsertGeneration() {
- return propertyInsertGeneration;
- }
-
- public boolean[] getPropertyUpdateGeneration() {
- return propertyUpdateGeneration;
- }
-
- public boolean[] getPropertyNullability() {
- return propertyNullability;
- }
-
- public boolean[] getPropertyVersionability() {
- return propertyVersionability;
- }
-
- public CascadeStyle[] getCascadeStyles() {
- return cascadeStyles;
- }
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-}
Added: trunk/Hibernate3/src/org/hibernate/tuple/EntityModeToTuplizerMapping.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/EntityModeToTuplizerMapping.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/EntityModeToTuplizerMapping.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -0,0 +1,72 @@
+package org.hibernate.tuple;
+
+import org.apache.commons.collections.SequencedHashMap;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+
+import java.util.Map;
+import java.util.Collections;
+import java.util.Iterator;
+import java.io.Serializable;
+
+/**
+ * Centralizes handling of {@link EntityMode} to {@link Tuplizer} mappings.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class EntityModeToTuplizerMapping implements Serializable {
+
+ // map of EntityMode -> Tuplizer
+ private final Map tuplizers = Collections.synchronizedMap( new SequencedHashMap() );
+
+ protected void addTuplizer(EntityMode entityMode, Tuplizer tuplizer) {
+ tuplizers.put( entityMode, tuplizer );
+ }
+
+ /**
+ * Given a supposed instance of an entity/component, guess its entity mode.
+ *
+ * @param object The supposed instance of the entity/component.
+ * @return The guessed entity mode.
+ */
+ public EntityMode guessEntityMode(Object object) {
+ Iterator itr = tuplizers.entrySet().iterator();
+ while( itr.hasNext() ) {
+ Map.Entry entry = ( Map.Entry ) itr.next();
+ Tuplizer tuplizer = ( Tuplizer ) entry.getValue();
+ if ( tuplizer.isInstance( object ) ) {
+ return ( EntityMode ) entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Locate the contained tuplizer responsible for the given entity-mode. If
+ * no such tuplizer is defined on this mapping, then return null.
+ *
+ * @param entityMode The entity-mode for which the caller wants a tuplizer.
+ * @return The tuplizer, or null if not found.
+ */
+ public Tuplizer getTuplizerOrNull(EntityMode entityMode) {
+ return ( Tuplizer ) tuplizers.get( entityMode );
+ }
+
+ /**
+ * Locate the tuplizer contained within this mapping which is responsible
+ * for the given entity-mode. If no such tuplizer is defined on this
+ * mapping, then an exception is thrown.
+ *
+ * @param entityMode The entity-mode for which the caller wants a tuplizer.
+ * @return The tuplizer.
+ * @throws HibernateException Unable to locate the requested tuplizer.
+ */
+ public Tuplizer getTuplizer(EntityMode entityMode) {
+ Tuplizer tuplizer = getTuplizerOrNull( entityMode );
+ if ( tuplizer == null ) {
+ throw new HibernateException( "No tuplizer found for entity-mode [" + entityMode + "]");
+ }
+ return tuplizer;
+ }
+}
Deleted: trunk/Hibernate3/src/org/hibernate/tuple/EntityTuplizer.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/tuple/EntityTuplizer.java 2006-07-13 21:38:41 UTC (rev 10118)
+++ trunk/Hibernate3/src/org/hibernate/tuple/EntityTuplizer.java 2006-07-14 00:09:19 UTC (rev 10119)
@@ -1,176 +0,0 @@
-//$Id$
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Defines further responsibilities reagarding tuplization based on
- * a mapped entity.
- * <p/>
- * EntityTuplizer implementations should have the following constructor signature:
- * (org.hibernate.tuple.EntityMetamodel, org.hibernate.mapping.PersistentClass)
- *
- * @author Gavin King
- */
-public interface EntityTuplizer extends Tuplizer {
-
- /**
- * Create an entity instance initialized with the given identifier.
- *
- * @param id The identifier value for the entity to be instantiated.
- * @return The instantiated entity.
- * @throws HibernateException
- */
- public Object instantiate(Serializable id) throws HibernateException;
-
- /**
- * Extract the ide...
[truncated message content] |
|
From: <hib...@li...> - 2006-07-13 21:39:30
|
Author: ste...@jb...
Date: 2006-07-13 17:38:41 -0400 (Thu, 13 Jul 2006)
New Revision: 10118
Modified:
trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCache.java
trunk/Hibernate3/src/org/hibernate/cache/StandardQueryCache.java
trunk/Hibernate3/src/org/hibernate/cache/UpdateTimestampsCache.java
Log:
corrections to OptimisticTreeCache; added some logging; formatting
Modified: trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCache.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCache.java 2006-07-13 04:06:48 UTC (rev 10117)
+++ trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCache.java 2006-07-13 21:38:41 UTC (rev 10118)
@@ -56,23 +56,15 @@
public void writeUpdate(Object key, Object value, Object currentVersion, Object previousVersion) {
try {
- Option option = null;
- if ( source != null ) {
- if ( source.isVersioned() ) {
- option = new Option();
- option.setDataVersion(
- new DataVersionAdapter(
- currentVersion,
- previousVersion,
- source.getVersionComparator()
- )
- );
- }
- }
+ Option option = new Option();
+ DataVersion dv = ( source != null && source.isVersioned() )
+ ? new DataVersionAdapter( currentVersion, previousVersion, source.getVersionComparator(), source.toString() )
+ : NonLockingDataVersion.INSTANCE;
+ option.setDataVersion( dv );
cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
}
- catch (Exception e) {
- throw new CacheException(e);
+ catch ( Exception e ) {
+ throw new CacheException( e );
}
}
@@ -80,18 +72,15 @@
try {
Option option = new Option();
option.setFailSilently( true );
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
cache.remove( new Fqn( regionFqn, key ), "ITEM", option );
- if ( source != null ) {
- if ( source.isVersioned() ) {
- option.setDataVersion(
- new DataVersionAdapter(
- currentVersion,
- null,
- source.getVersionComparator()
- )
- );
- }
- }
+
+ option = new Option();
+ option.setFailSilently( true );
+ DataVersion dv = ( source != null && source.isVersioned() )
+ ? new DataVersionAdapter( currentVersion, currentVersion, source.getVersionComparator(), source.toString() )
+ : NonLockingDataVersion.INSTANCE;
+ option.setDataVersion( dv );
cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
}
catch (Exception e) {
@@ -106,6 +95,7 @@
try {
Option option = new Option();
option.setFailSilently( true );
+// option.setDataVersion( NonLockingDataVersion.INSTANCE );
return cache.get( new Fqn( regionFqn, key ), ITEM, option );
}
catch (Exception e) {
@@ -124,7 +114,9 @@
public void update(Object key, Object value) throws CacheException {
try {
- cache.put( new Fqn( regionFqn, key ), ITEM, value );
+ Option option = new Option();
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
}
catch (Exception e) {
throw new CacheException(e);
@@ -133,9 +125,11 @@
public void put(Object key, Object value) throws CacheException {
try {
+ log.trace( "performing put() into region [" + regionName + "]" );
// do the put outside the scope of the JTA txn
Option option = new Option();
option.setFailSilently( true );
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
cache.put( new Fqn( regionFqn, key ), ITEM, value, option );
}
catch (TimeoutException te) {
@@ -149,7 +143,16 @@
public void remove(Object key) throws CacheException {
try {
- cache.remove( new Fqn( regionFqn, key ) );
+ // tree cache in optimistic mode seems to have as very difficult
+ // time with remove calls on non-existent nodes (NPEs)...
+ if ( cache.get( new Fqn( regionFqn, key ), ITEM ) != null ) {
+ Option option = new Option();
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ cache.remove( new Fqn( regionFqn, key ), option );
+ }
+ else {
+ log.trace( "skipping remove() call as the underlying node did not seem to exist" );
+ }
}
catch (Exception e) {
throw new CacheException(e);
@@ -158,7 +161,9 @@
public void clear() throws CacheException {
try {
- cache.remove( regionFqn );
+ Option option = new Option();
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
+ cache.remove( regionFqn, option );
}
catch (Exception e) {
throw new CacheException(e);
@@ -169,6 +174,8 @@
try {
Option option = new Option();
option.setCacheModeLocal( true );
+ option.setFailSilently( true );
+ option.setDataVersion( NonLockingDataVersion.INSTANCE );
cache.remove( regionFqn, option );
}
catch( Exception e ) {
@@ -243,19 +250,80 @@
private final Object currentVersion;
private final Object previousVersion;
private final Comparator versionComparator;
+ private final String sourceIdentifer;
- public DataVersionAdapter(Object currentVersion, Object previousVersion, Comparator versionComparator) {
+ public DataVersionAdapter(Object currentVersion, Object previousVersion, Comparator versionComparator, String sourceIdentifer) {
this.currentVersion = currentVersion;
this.previousVersion = previousVersion;
this.versionComparator = versionComparator;
+ this.sourceIdentifer = sourceIdentifer;
+ log.trace( "created " + this );
}
+ /**
+ * newerThan() call is dispatched against the DataVersion currently
+ * associated with the node; the passed dataVersion param is the
+ * DataVersion associated with the data we are trying to put into
+ * the node.
+ * <p/>
+ * we are expected to return true in the case where we (the current
+ * node DataVersion) are newer that then incoming value. Returning
+ * true here essentially means that a optimistic lock failure has
+ * occured (because conversely, the value we are trying to put into
+ * the node is "older than" the value already there...)
+ */
public boolean newerThan(DataVersion dataVersion) {
- if ( previousVersion == null ) {
- log.warn( "Unexpected optimistic lock check on inserted data" );
+ log.trace( "checking [" + this + "] against [" + dataVersion + "]" );
+ if ( dataVersion instanceof CircumventChecksDataVersion ) {
+ log.trace( "skipping lock checks..." );
+ return false;
}
- Object other = ( ( DataVersionAdapter ) dataVersion ).currentVersion;
- return versionComparator.compare( previousVersion, other ) > 1;
+ else if ( dataVersion instanceof NonLockingDataVersion ) {
+ // can happen because of the multiple ways Cache.remove()
+ // can be invoked :(
+ log.trace( "skipping lock checks..." );
+ return false;
+ }
+ DataVersionAdapter other = ( DataVersionAdapter ) dataVersion;
+ if ( other.previousVersion == null ) {
+ log.warn( "Unexpected optimistic lock check on inserting data" );
+ // work around the "feature" where tree cache is validating the
+ // inserted node during the next transaction. no idea...
+ if ( this == dataVersion ) {
+ log.trace( "skipping lock checks due to same DV instance" );
+ return false;
+ }
+ }
+ return versionComparator.compare( currentVersion, other.previousVersion ) >= 1;
}
+
+ public String toString() {
+ return super.toString() + " [current=" + currentVersion + ", previous=" + previousVersion + ", src=" + sourceIdentifer + "]";
+ }
}
+
+ /**
+ * Used in regions where no locking should ever occur. This includes query-caches,
+ * update-timestamps caches, collection caches, and entity caches where the entity
+ * is not versioned.
+ */
+ public static class NonLockingDataVersion implements DataVersion {
+ public static final DataVersion INSTANCE = new NonLockingDataVersion();
+ public boolean newerThan(DataVersion dataVersion) {
+ log.trace( "non locking lock check...");
+ return false;
+ }
+ }
+
+ /**
+ * Used to signal to a DataVersionAdapter to simply not perform any checks. This
+ * is currently needed for proper handling of remove() calls for entity cache regions
+ * (we do not know the version info...).
+ */
+ public static class CircumventChecksDataVersion implements DataVersion {
+ public static final DataVersion INSTANCE = new CircumventChecksDataVersion();
+ public boolean newerThan(DataVersion dataVersion) {
+ throw new CacheException( "optimistic locking checks should never happen on CircumventChecksDataVersion" );
+ }
+ }
}
Modified: trunk/Hibernate3/src/org/hibernate/cache/StandardQueryCache.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cache/StandardQueryCache.java 2006-07-13 04:06:48 UTC (rev 10117)
+++ trunk/Hibernate3/src/org/hibernate/cache/StandardQueryCache.java 2006-07-13 21:38:41 UTC (rev 10118)
@@ -27,7 +27,7 @@
*/
public class StandardQueryCache implements QueryCache {
- private static final Log log = LogFactory.getLog(StandardQueryCache.class);
+ private static final Log log = LogFactory.getLog( StandardQueryCache.class );
private Cache queryCache;
private UpdateTimestampsCache updateTimestampsCache;
@@ -41,34 +41,40 @@
final Settings settings,
final Properties props,
final UpdateTimestampsCache updateTimestampsCache,
- String regionName)
- throws HibernateException {
-
- if (regionName==null) regionName = StandardQueryCache.class.getName();
+ String regionName) throws HibernateException {
+ if ( regionName == null ) {
+ regionName = StandardQueryCache.class.getName();
+ }
String prefix = settings.getCacheRegionPrefix();
- if (prefix!=null) regionName = prefix + '.' + regionName;
-
- log.info("starting query cache at region: " + regionName);
-
+ if ( prefix != null ) {
+ regionName = prefix + '.' + regionName;
+ }
+ log.info( "starting query cache at region: " + regionName );
+
this.queryCache = settings.getCacheProvider().buildCache(regionName, props);
this.updateTimestampsCache = updateTimestampsCache;
this.regionName = regionName;
}
- public boolean put(QueryKey key, Type[] returnTypes, List result, boolean isNaturalKeyLookup, SessionImplementor session)
- throws HibernateException {
+ public boolean put(
+ QueryKey key,
+ Type[] returnTypes,
+ List result,
+ boolean isNaturalKeyLookup,
+ SessionImplementor session) throws HibernateException {
if ( isNaturalKeyLookup && result.size()==0 ) {
return false;
}
else {
-
+ Long ts = new Long( session.getTimestamp() );
+
if ( log.isDebugEnabled() ) {
- log.debug("caching query results in region: " + regionName);
+ log.debug( "caching query results in region: " + regionName + "; timestamp=" + ts );
}
List cacheable = new ArrayList( result.size()+1 );
- cacheable.add( new Long( session.getTimestamp() ) );
+ cacheable.add( ts );
for ( int i=0; i<result.size(); i++ ) {
if ( returnTypes.length==1 ) {
cacheable.add( returnTypes[0].disassemble( result.get(i), session, null ) );
@@ -86,25 +92,28 @@
}
- public List get(QueryKey key, Type[] returnTypes, boolean isNaturalKeyLookup, Set spaces, SessionImplementor session)
- throws HibernateException {
-
+ public List get(
+ QueryKey key,
+ Type[] returnTypes,
+ boolean isNaturalKeyLookup,
+ Set spaces,
+ SessionImplementor session) throws HibernateException {
if ( log.isDebugEnabled() ) {
log.debug("checking cached query results in region: " + regionName);
}
-
+
List cacheable = (List) queryCache.get(key);
if (cacheable==null) {
log.debug("query results were not found in cache");
return null;
}
-
+
Long timestamp = (Long) cacheable.get(0);
if ( !isNaturalKeyLookup && !isUpToDate(spaces, timestamp) ) {
log.debug("cached query results were not up to date");
return null;
}
-
+
log.debug("returning cached query results");
for ( int i=1; i<cacheable.size(); i++ ) {
if ( returnTypes.length==1 ) {
Modified: trunk/Hibernate3/src/org/hibernate/cache/UpdateTimestampsCache.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/cache/UpdateTimestampsCache.java 2006-07-13 04:06:48 UTC (rev 10117)
+++ trunk/Hibernate3/src/org/hibernate/cache/UpdateTimestampsCache.java 2006-07-13 21:38:41 UTC (rev 10118)
@@ -18,37 +18,37 @@
* to a higher value than the timeouts of any of the query caches. In fact, we
* recommend that the the underlying cache not be configured for expiry at all.
* Note, in particular, that an LRU cache expiry policy is never appropriate.
- * @author Gavin King, Mikheil Kapanadze
+ *
+ * @author Gavin King
+ * @author Mikheil Kapanadze
*/
public class UpdateTimestampsCache {
+ public static final String REGION_NAME = UpdateTimestampsCache.class.getName();
+
private static final Log log = LogFactory.getLog(UpdateTimestampsCache.class);
private Cache updateTimestamps;
private final String regionName;
- public static final String REGION_NAME = UpdateTimestampsCache.class.getName();
-
public void clear() throws CacheException {
updateTimestamps.clear();
}
- public UpdateTimestampsCache(Settings settings, Properties props)
- throws HibernateException {
+ public UpdateTimestampsCache(Settings settings, Properties props) throws HibernateException {
String prefix = settings.getCacheRegionPrefix();
-
- regionName = prefix==null ?
- REGION_NAME :
- prefix + '.' + REGION_NAME;
- log.info("starting update timestamps cache at region: " + regionName);
- this.updateTimestamps = settings.getCacheProvider().buildCache(regionName, props);
+ regionName = prefix == null ? REGION_NAME : prefix + '.' + REGION_NAME;
+ log.info( "starting update timestamps cache at region: " + regionName );
+ this.updateTimestamps = settings.getCacheProvider().buildCache( regionName, props );
}
public synchronized void preinvalidate(Serializable[] spaces) throws CacheException {
//TODO: to handle concurrent writes correctly, this should return a Lock to the client
Long ts = new Long( updateTimestamps.nextTimestamp() + updateTimestamps.getTimeout() );
for ( int i=0; i<spaces.length; i++ ) {
- if ( log.isDebugEnabled() ) log.debug("Pre-invalidating space [" + spaces[i] + "]");
+ if ( log.isDebugEnabled() ) {
+ log.debug( "Pre-invalidating space [" + spaces[i] + "]" );
+ }
//put() has nowait semantics, is this really appropriate?
//note that it needs to be async replication, never local or sync
updateTimestamps.put( spaces[i], ts );
@@ -61,7 +61,9 @@
Long ts = new Long( updateTimestamps.nextTimestamp() );
//TODO: if lock.getTimestamp().equals(ts)
for ( int i=0; i<spaces.length; i++ ) {
- if ( log.isDebugEnabled() ) log.debug("Invalidating space [" + spaces[i] + "], timestamp: " + ts);
+ if ( log.isDebugEnabled() ) {
+ log.debug( "Invalidating space [" + spaces[i] + "], timestamp: " + ts);
+ }
//put() has nowait semantics, is this really appropriate?
//note that it needs to be async replication, never local or sync
updateTimestamps.put( spaces[i], ts );
@@ -83,7 +85,8 @@
if ( log.isDebugEnabled() ) {
log.debug("[" + space + "] last update timestamp: " + lastUpdate + ", result set timestamp: " + timestamp );
}
- if ( lastUpdate.longValue() >= timestamp.longValue() ) return false;
+ return lastUpdate.longValue() < timestamp.longValue();
+// if ( lastUpdate.longValue() >= timestamp.longValue() ) return false;
}
}
return true;
|
|
From: <hib...@li...> - 2006-07-13 04:07:07
|
Author: ste...@jb... Date: 2006-07-13 00:06:48 -0400 (Thu, 13 Jul 2006) New Revision: 10117 Modified: branches/Hibernate_3_1_3_JBAS-3375/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java Log: applied appropriate changeset (http://fisheye.jboss.com/changelog/Hibernate?cs=9919) Modified: branches/Hibernate_3_1_3_JBAS-3375/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java =================================================================== --- branches/Hibernate_3_1_3_JBAS-3375/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java 2006-07-13 03:31:21 UTC (rev 10116) +++ branches/Hibernate_3_1_3_JBAS-3375/Hibernate3/src/org/hibernate/engine/transaction/Isolater.java 2006-07-13 04:06:48 UTC (rev 10117) @@ -186,8 +186,8 @@ catch( Throwable ignore ) { log.trace( "was unable to reset connection back to auto-commit" ); } - session.getBatcher().closeConnection( connection ); } + session.getBatcher().closeConnection( connection ); } } } |
|
From: <hib...@li...> - 2006-07-13 03:31:29
|
Author: ste...@jb... Date: 2006-07-12 23:31:21 -0400 (Wed, 12 Jul 2006) New Revision: 10116 Added: branches/Hibernate_3_1_3_JBAS-3375/Hibernate3/ Log: copied v313 as base for patch Copied: branches/Hibernate_3_1_3_JBAS-3375/Hibernate3 (from rev 10115, tags/v313/Hibernate3) |
|
From: <hib...@li...> - 2006-07-13 03:29:11
|
Author: ste...@jb... Date: 2006-07-12 23:29:06 -0400 (Wed, 12 Jul 2006) New Revision: 10115 Added: branches/Hibernate_3_1_3_JBAS-3375/ Log: patch branch for JBAS-3375 |
|
From: <hib...@li...> - 2006-07-13 02:16:28
|
Author: epbernard
Date: 2006-07-12 22:16:13 -0400 (Wed, 12 Jul 2006)
New Revision: 10114
Added:
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/FieldBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/LuceneSession.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/BridgeFactory.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DateBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DoubleBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FloatBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IntegerBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/LongBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/NumberBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/ParameterizedBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/Resolution.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringImplBridge.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/EntityInfo.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/IteratorImpl.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/LuceneQueryImpl.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/ScrollableResultsImpl.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/util/
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/util/BinderHelper.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/MappingTest.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/TestCase.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/query/
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/query/Book.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/query/Clock.java
branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/query/QueryTest.java
Modified:
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java
branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java
Log:
Prototype for Hibernate Lucene Query + field bridge
Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/DocumentBuilder.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -1,7 +1,6 @@
//$Id$
package org.hibernate.lucene;
-import java.beans.Introspector;
import java.io.Serializable;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
@@ -17,8 +16,13 @@
import org.apache.lucene.index.Term;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
import org.hibernate.cfg.annotations.Version;
import org.hibernate.lucene.store.DirectoryProvider;
+import org.hibernate.lucene.bridge.FieldBridge;
+import org.hibernate.lucene.bridge.BridgeFactory;
+import org.hibernate.lucene.util.BinderHelper;
+import org.hibernate.lucene.event.LuceneEventListener;
//TODO handle attribute (only getters are handled currently)
public class DocumentBuilder<T> {
@@ -39,6 +43,8 @@
private String idKeywordName;
private final Analyzer analyzer;
private Float idBoost;
+ public static final String CLASS_FIELDNAME = "_hibernate_class";
+ private FieldBridge idBridge;
public DocumentBuilder(Class<?> clazz, Analyzer analyzer, DirectoryProvider directory) {
//this.beanClass = clazz;
@@ -51,10 +57,11 @@
Method method = methods[i];
Keyword keywordAnn = method.getAnnotation( Keyword.class );
if ( keywordAnn != null ) {
- String name = getAttributeName( method, keywordAnn.name() );
+ String name = BinderHelper.getAttributeName( method, keywordAnn.name() );
if ( keywordAnn.id() ) {
idKeywordName = name;
idBoost = getBoost( method );
+ idBridge = BridgeFactory.guessType( method );
}
else {
setAccessible( method );
@@ -66,12 +73,12 @@
if ( unstoredAnn != null ) {
setAccessible( method );
unstoredGetters.add( method );
- unstoredNames.add( getAttributeName( method, unstoredAnn.name() ) );
+ unstoredNames.add( BinderHelper.getAttributeName( method, unstoredAnn.name() ) );
}
Text textAnn = method.getAnnotation( Text.class );
if ( textAnn != null ) {
textGetters.add( method );
- textNames.add( getAttributeName( method, textAnn.name() ) );
+ textNames.add( BinderHelper.getAttributeName( method, textAnn.name() ) );
}
}
}
@@ -111,11 +118,9 @@
doc.setBoost( boost.floatValue() );
}
{
- Field idField = new Field( idKeywordName, id.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED );
- if (idBoost != null) {
- idField.setBoost( idBoost.floatValue() );
- }
- doc.add( idField );
+ Field classField = new Field( CLASS_FIELDNAME, instance.getClass().getName(), Field.Store.YES, Field.Index.NO);
+ doc.add( classField );
+ idBridge.set( idKeywordName, id, doc, Field.Store.YES, Field.Index.UN_TOKENIZED, idBoost );
}
for ( int i = 0; i < keywordNames.size() ; i++ ) {
Member member = keywordGetters.get( i );
@@ -161,19 +166,6 @@
return new Term( idKeywordName, id.toString() );
}
- private static String getAttributeName(Method method, String name) {
- if( ! "".equals( name ) ) return name; //explicit field name
-
- //decapitalize
- String methodName = method.getName();
- //FIXME we probably should exclude methods not starting with "get" nor "is"
- int startIndex = 3;
- if( methodName.startsWith("is") ) {
- startIndex = 2;
- }
- return Introspector.decapitalize( methodName.substring( startIndex ) );
- }
-
public DirectoryProvider getDirectoryProvider() {
return directoryProvider;
}
@@ -187,4 +179,30 @@
( (AccessibleObject) member ).setAccessible( true );
}
}
+
+ public FieldBridge getIdBridge() {
+ return idBridge;
+ }
+
+ public String getIdKeywordName() {
+ return idKeywordName;
+ }
+
+ public static Class getDocumentClass(Document document) {
+ String className = document.get( DocumentBuilder.CLASS_FIELDNAME );
+ try {
+ return ReflectHelper.classForName( className );
+ }
+ catch (ClassNotFoundException e) {
+ throw new HibernateException("Unable to load indexed class: " + className, e);
+ }
+ }
+
+ public static Serializable getDocumentId(LuceneEventListener listener, Class clazz, Document document) {
+ DocumentBuilder builder = listener.getDocumentBuilders().get( clazz );
+ if (builder == null) throw new HibernateException("No Lucene configuration set up for: " + clazz.getName() );
+ Serializable id = (Serializable) builder.getIdBridge().get( builder.getIdKeywordName(), document );
+ return id;
+ }
+
}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/FieldBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/FieldBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/FieldBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,22 @@
+//$Id: $
+package org.hibernate.lucene;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Documented;
+
+import org.hibernate.annotations.Parameter;
+
+/**
+ * specifies a given field bridge implementation
+ * @author Emmanuel Bernard
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+@Documented
+public @interface FieldBridge {
+ public Class impl() default void.class;
+ public Parameter[] params() default {};
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/LuceneSession.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/LuceneSession.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/LuceneSession.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,408 @@
+//$Id: $
+package org.hibernate.lucene;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.Filter;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ReplicationMode;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.NotYetImplementedException;
+import org.hibernate.engine.query.ParameterMetadata;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.lucene.query.LuceneQueryImpl;
+import org.hibernate.stat.SessionStatistics;
+import org.hibernate.type.Type;
+
+/**
+ * Lucene aware session that allows lucene query creations
+ *
+ * @author Emmanuel Bernard
+ */
+public class LuceneSession implements Session {
+ private final SessionImpl session;
+
+ public LuceneSession(Session session) {
+ this.session = (SessionImpl) session;
+ }
+
+ /**
+ * Execute a Lucene query and retrieve managed objects
+ * @param entities must be immutable for the lifetime of the query object
+ */
+ public Query createLuceneQuery(org.apache.lucene.search.Query luceneQuery, Class... entities) {
+ return new LuceneQueryImpl( luceneQuery, entities, session, new ParameterMetadata(null, null) );
+ }
+
+ public void index(Object object) {
+ throw new NotYetImplementedException("");
+ //TODO
+ //need to add elements in a queue kept at the Session level
+ //the queue will be processed by a Lucene(Auto)FlushEventListener
+ //note that we could keep this queue somewhere in the event listener in the mean time but that requires
+ // a synchronized hashmap holding this queue on a per session basis plus some session house keeping (yuk)
+ //an other solution would be to subclass SessionImpl instead of having this LuceneSession delecation model
+ // this is an open discussion
+ }
+
+ public Query createSQLQuery(String sql, String returnAlias, Class returnClass) {
+ return session.createSQLQuery( sql, returnAlias, returnClass );
+ }
+
+ public Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses) {
+ return session.createSQLQuery( sql, returnAliases, returnClasses );
+ }
+
+ 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 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 session.filter( collection, filter, value, type );
+ }
+
+ public Collection filter(Object collection, String filter, Object[] values, Type[] types) throws HibernateException {
+ return session.filter( collection, filter, values, types );
+ }
+
+ 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 void save(String entityName, Object object, Serializable id) throws HibernateException {
+ session.save( entityName, object, id );
+ }
+
+ public void save(Object object, Serializable id) throws HibernateException {
+ session.save( object, id );
+ }
+
+ public Object saveOrUpdateCopy(String entityName, Object object) throws HibernateException {
+ return session.saveOrUpdateCopy( entityName, object );
+ }
+
+ public Object saveOrUpdateCopy(String entityName, Object object, Serializable id) throws HibernateException {
+ return session.saveOrUpdateCopy( entityName, object, id );
+ }
+
+ public Object saveOrUpdateCopy(Object object) throws HibernateException {
+ return session.saveOrUpdateCopy( object );
+ }
+
+ public Object saveOrUpdateCopy(Object object, Serializable id) throws HibernateException {
+ return session.saveOrUpdateCopy( object, id );
+ }
+
+ public void update(String entityName, Object object, Serializable id) throws HibernateException {
+ session.update( entityName, object, id );
+ }
+
+ public void update(Object object, Serializable id) throws HibernateException {
+ session.update( object, id );
+ }
+
+ public Transaction beginTransaction() throws HibernateException {
+ return session.beginTransaction();
+ }
+
+ public void cancelQuery() throws HibernateException {
+ session.cancelQuery();
+ }
+
+ public void clear() {
+ session.clear();
+ }
+
+ public Connection close() throws HibernateException {
+ return session.close();
+ }
+
+ public Connection connection() throws HibernateException {
+ return session.connection();
+ }
+
+ public boolean contains(Object object) {
+ return session.contains( object );
+ }
+
+ public Criteria createCriteria(String entityName) {
+ return session.createCriteria( entityName );
+ }
+
+ public Criteria createCriteria(String entityName, String alias) {
+ return session.createCriteria( entityName, alias );
+ }
+
+ public Criteria createCriteria(Class persistentClass) {
+ return session.createCriteria( persistentClass );
+ }
+
+ public Criteria createCriteria(Class persistentClass, String alias) {
+ return session.createCriteria( persistentClass, alias );
+ }
+
+ public Query createFilter(Object collection, String queryString) throws HibernateException {
+ return session.createFilter( collection, queryString );
+ }
+
+ public Query createQuery(String queryString) throws HibernateException {
+ return session.createQuery( queryString );
+ }
+
+ public SQLQuery createSQLQuery(String queryString) throws HibernateException {
+ return session.createSQLQuery( queryString );
+ }
+
+ public void delete(String entityName, Object object) throws HibernateException {
+ session.delete( entityName, object );
+ }
+
+ public void delete(Object object) throws HibernateException {
+ session.delete( object );
+ }
+
+ public void disableFilter(String filterName) {
+ session.disableFilter( filterName );
+ }
+
+ public Connection disconnect() throws HibernateException {
+ return session.disconnect();
+ }
+
+ public Filter enableFilter(String filterName) {
+ return session.enableFilter( filterName );
+ }
+
+ public void evict(Object object) throws HibernateException {
+ session.evict( object );
+ }
+
+ public void flush() throws HibernateException {
+ session.flush();
+ }
+
+ public Object get(Class clazz, Serializable id) throws HibernateException {
+ return session.get( clazz, id );
+ }
+
+ public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException {
+ return session.get( clazz, id, lockMode );
+ }
+
+ public Object get(String entityName, Serializable id) throws HibernateException {
+ return session.get( entityName, id );
+ }
+
+ public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
+ return session.get( entityName, id, lockMode );
+ }
+
+ public CacheMode getCacheMode() {
+ return session.getCacheMode();
+ }
+
+ public LockMode getCurrentLockMode(Object object) throws HibernateException {
+ return session.getCurrentLockMode( object );
+ }
+
+ public Filter getEnabledFilter(String filterName) {
+ return session.getEnabledFilter( filterName );
+ }
+
+ public EntityMode getEntityMode() {
+ return session.getEntityMode();
+ }
+
+ public String getEntityName(Object object) throws HibernateException {
+ return session.getEntityName( object );
+ }
+
+ public FlushMode getFlushMode() {
+ return session.getFlushMode();
+ }
+
+ public Serializable getIdentifier(Object object) throws HibernateException {
+ return session.getIdentifier( object );
+ }
+
+ public Query getNamedQuery(String queryName) throws HibernateException {
+ return session.getNamedQuery( queryName );
+ }
+
+ public org.hibernate.Session getSession(EntityMode entityMode) {
+ return session.getSession( entityMode );
+ }
+
+ public SessionFactory getSessionFactory() {
+ return session.getSessionFactory();
+ }
+
+ public SessionStatistics getStatistics() {
+ return session.getStatistics();
+ }
+
+ public Transaction getTransaction() {
+ return session.getTransaction();
+ }
+
+ public boolean isConnected() {
+ return session.isConnected();
+ }
+
+ public boolean isDirty() throws HibernateException {
+ return session.isDirty();
+ }
+
+ public boolean isOpen() {
+ return session.isOpen();
+ }
+
+ public Object load(String entityName, Serializable id) throws HibernateException {
+ return session.load( entityName, id );
+ }
+
+ public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
+ return session.load( entityName, id, lockMode );
+ }
+
+ public void load(Object object, Serializable id) throws HibernateException {
+ session.load( object, id );
+ }
+
+ public Object load(Class theClass, Serializable id) throws HibernateException {
+ return session.load( theClass, id );
+ }
+
+ public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException {
+ return session.load( theClass, id, lockMode );
+ }
+
+ public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException {
+ session.lock( entityName, object, lockMode );
+ }
+
+ public void lock(Object object, LockMode lockMode) throws HibernateException {
+ session.lock( object, lockMode );
+ }
+
+ public Object merge(String entityName, Object object) throws HibernateException {
+ return session.merge( entityName, object );
+ }
+
+ public Object merge(Object object) throws HibernateException {
+ return session.merge( object );
+ }
+
+ public void persist(String entityName, Object object) throws HibernateException {
+ session.persist( entityName, object );
+ }
+
+ public void persist(Object object) throws HibernateException {
+ session.persist( object );
+ }
+
+ public void reconnect() throws HibernateException {
+ session.reconnect();
+ }
+
+ public void reconnect(Connection connection) throws HibernateException {
+ session.reconnect( connection );
+ }
+
+ public void refresh(Object object) throws HibernateException {
+ session.refresh( object );
+ }
+
+ public void refresh(Object object, LockMode lockMode) throws HibernateException {
+ session.refresh( object, lockMode );
+ }
+
+ public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException {
+ session.replicate( entityName, object, replicationMode );
+ }
+
+ public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException {
+ session.replicate( object, replicationMode );
+ }
+
+ public Serializable save(String entityName, Object object) throws HibernateException {
+ return session.save( entityName, object );
+ }
+
+ public Serializable save(Object object) throws HibernateException {
+ return session.save( object );
+ }
+
+ public void saveOrUpdate(String entityName, Object object) throws HibernateException {
+ session.saveOrUpdate( entityName, object );
+ }
+
+ public void saveOrUpdate(Object object) throws HibernateException {
+ session.saveOrUpdate( object );
+ }
+
+ public void setCacheMode(CacheMode cacheMode) {
+ session.setCacheMode( cacheMode );
+ }
+
+ public void setFlushMode(FlushMode flushMode) {
+ session.setFlushMode( flushMode );
+ }
+
+ public void setReadOnly(Object entity, boolean readOnly) {
+ session.setReadOnly( entity, readOnly );
+ }
+
+ public void update(String entityName, Object object) throws HibernateException {
+ session.update( entityName, object );
+ }
+
+ public void update(Object object) throws HibernateException {
+ session.update( object );
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/BridgeFactory.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/BridgeFactory.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/BridgeFactory.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,99 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Member;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.annotations.Parameter;
+import org.hibernate.lucene.util.BinderHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BridgeFactory {
+ private static Map<String, FieldBridge> builtInBridges = new HashMap<String, FieldBridge>();
+ private BridgeFactory() {}
+
+ public static final FieldBridge DOUBLE = new String2FieldBridgeAdaptor( new DoubleBridge() );
+
+ public static final FieldBridge FLOAT = new String2FieldBridgeAdaptor( new FloatBridge() );
+
+ public static final FieldBridge INTEGER = new String2FieldBridgeAdaptor( new IntegerBridge() );
+
+ public static final FieldBridge LONG = new String2FieldBridgeAdaptor( new LongBridge() );
+
+ public static final FieldBridge STRING = new String2FieldBridgeAdaptor( new StringImplBridge() );
+
+ public static final FieldBridge DATE_YEAR;
+ public static final FieldBridge DATE_MONTH;
+ public static final FieldBridge DATE_DAY;
+ public static final FieldBridge DATE_HOUR;
+ public static final FieldBridge DATE_MINUTE;
+ public static final FieldBridge DATE_SECOND;
+ public static final FieldBridge DATE_MILLISECOND;
+
+ static {
+ builtInBridges.put( Double.class.getName(), DOUBLE );
+ builtInBridges.put( Float.class.getName(), FLOAT );
+ builtInBridges.put( Integer.class.getName(), INTEGER );
+ builtInBridges.put( Long.class.getName(), LONG );
+ builtInBridges.put( String.class.getName(), STRING );
+
+ DATE_YEAR = createDateBridge( Resolution.YEAR );
+ DATE_MONTH = createDateBridge( Resolution.MONTH );
+ DATE_DAY = createDateBridge( Resolution.DAY );
+ DATE_HOUR = createDateBridge( Resolution.HOUR );
+ DATE_MINUTE = createDateBridge( Resolution.MINUTE );
+ DATE_SECOND = createDateBridge( Resolution.SECOND );
+ DATE_MILLISECOND = createDateBridge( Resolution.MILLISECOND );
+ builtInBridges.put( Date.class.getName(), DATE_MILLISECOND );
+ }
+
+ private static FieldBridge createDateBridge(Resolution resolution) {
+ DateBridge date;
+ Map params = new HashMap(1);
+ params.put( "resolution", resolution );
+ date = new DateBridge();
+ date.setParameterValues( params );
+ return new String2FieldBridgeAdaptor( date );
+ }
+
+ public static FieldBridge guessType(Member member) {
+ FieldBridge bridge = null;
+ org.hibernate.lucene.FieldBridge bridgeAnn = ( (AnnotatedElement) member ).getAnnotation( org.hibernate.lucene.FieldBridge.class );
+ if (bridgeAnn != null) {
+ Class impl = bridgeAnn.impl();
+ try {
+ Object instance = impl.newInstance();
+ if ( FieldBridge.class.isAssignableFrom( impl ) ) {
+ bridge = (FieldBridge) instance;
+ }
+ else if ( StringBridge.class.isAssignableFrom( impl ) ) {
+ bridge = new String2FieldBridgeAdaptor( (StringBridge) instance );
+ }
+ if ( bridgeAnn.params().length > 0 && ParameterizedBridge.class.isAssignableFrom( impl ) ) {
+ Map params = new HashMap( bridgeAnn.params().length );
+ for ( Parameter param : bridgeAnn.params() ) {
+ params.put( param.name(), param.value() );
+ }
+ ( (ParameterizedBridge) instance ).setParameterValues( params );
+ }
+ }
+ catch (Exception e) {
+ throw new HibernateException("Unable to instanciate FieldBridge for " + BinderHelper.getAttributeName(member), e );
+ }
+ }
+ else {
+ //find in built-ins
+ Class<?> returnType = BinderHelper.getReturnType( member );
+ bridge = builtInBridges.get( returnType.getName() );
+ }
+ if (bridge == null) throw new HibernateException("Unable to guess FieldBridge for " + BinderHelper.getAttributeName(member) );
+ return bridge;
+ }
+
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DateBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DateBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DateBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,62 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.lucene.document.DateTools;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DateBridge implements StringBridge, ParameterizedBridge {
+ //TODO don't depend on such a weak 3rd party API for a public API of ours
+ DateTools.Resolution resolution;
+
+ public Object stringToObject(String stringValue) {
+ //usually does not make sense
+ try {
+ return DateTools.stringToDate( stringValue );
+ }
+ catch (ParseException e) {
+ throw new HibernateException( "Unable to parse into date: " + stringValue, e );
+ }
+ }
+
+ public String objectToString(Object object) {
+ return DateTools.dateToString( (Date) object, resolution );
+ }
+
+ public void setParameterValues(Map parameters) {
+ Resolution hibResolution = (Resolution) parameters.get( "resolution" );
+ switch ( hibResolution ) {
+ case YEAR:
+ resolution = DateTools.Resolution.YEAR;
+ break;
+ case MONTH:
+ resolution = DateTools.Resolution.MONTH;
+ break;
+ case DAY:
+ resolution = DateTools.Resolution.DAY;
+ break;
+ case HOUR:
+ resolution = DateTools.Resolution.HOUR;
+ break;
+ case MINUTE:
+ resolution = DateTools.Resolution.MINUTE;
+ break;
+ case SECOND:
+ resolution = DateTools.Resolution.SECOND;
+ break;
+ case MILLISECOND:
+ resolution = DateTools.Resolution.MILLISECOND;
+ break;
+ default:
+ throw new AssertionFailure( "Unknown Resolution: " + hibResolution );
+
+ }
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DoubleBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DoubleBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/DoubleBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,11 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DoubleBridge extends NumberBridge {
+ public Object stringToObject(String stringValue) {
+ return new Double(stringValue);
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FieldBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,18 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+
+/**
+ * Link between a java property and a Lucene Document
+ * Usually a Java property will be linked to a Document Field
+ *
+ * @author Emmanuel Bernard
+ */
+//TODO should show Field or document?
+//document is nice since I can save an object into several fields
+public interface FieldBridge {
+ Object get(String name, Document document);
+ void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost);
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FloatBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FloatBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/FloatBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,11 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class FloatBridge extends NumberBridge {
+ public Object stringToObject(String stringValue) {
+ return new Float(stringValue);
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IntegerBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IntegerBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/IntegerBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,11 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IntegerBridge extends NumberBridge {
+ public Object stringToObject(String stringValue) {
+ return new Integer(stringValue);
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/LongBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/LongBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/LongBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,11 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class LongBridge extends NumberBridge {
+ public Object stringToObject(String stringValue) {
+ return new Long(stringValue);
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/NumberBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/NumberBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/NumberBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,11 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class NumberBridge implements StringBridge {
+ public String objectToString(Object object) {
+ return object.toString();
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/ParameterizedBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/ParameterizedBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/ParameterizedBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,13 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import java.util.Map;
+
+/**
+ * Allow parameter injection to a given bridge
+ *
+ * @author Emmanuel Bernard
+ */
+public interface ParameterizedBridge {
+ void setParameterValues(Map parameters);
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/Resolution.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/Resolution.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/Resolution.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,17 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * Date indexing resolution
+ *
+ * @author Emmanuel Bernard
+ */
+public enum Resolution {
+ YEAR,
+ MONTH,
+ DAY,
+ HOUR,
+ MINUTE,
+ SECOND,
+ MILLISECOND
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/String2FieldBridgeAdaptor.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,31 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+
+/**
+ * Bridge to use a Java2String as a Java2Field
+ *
+ * @author Emmanuel Bernard
+ */
+public class String2FieldBridgeAdaptor implements FieldBridge {
+
+ private StringBridge stringBridge;
+
+ public String2FieldBridgeAdaptor(StringBridge stringBridge) {
+ this.stringBridge = stringBridge;
+ }
+ public Object get(String name, Document document) {
+ Field field = document.getField( name );
+ return stringBridge.stringToObject( field.stringValue() );
+ }
+
+ public void set(String name, Object value, Document document, Field.Store store, Field.Index index, Float boost) {
+ Field field = new Field(name, stringBridge.objectToString( value ), store, index);
+ if (boost != null) field.setBoost( boost );
+ document.add( field );
+ }
+
+
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,20 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * Transform an object into a stirng representation and vice versa
+ *
+ * @author Emmanuel Bernard
+ */
+public interface StringBridge {
+ /**
+ * Convert the string representation to an object
+ * FIXME: This operation might not always be possible
+ */
+ Object stringToObject(String stringValue);
+
+ /**
+ * convert the object representation to a String
+ */
+ String objectToString(Object object);
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringImplBridge.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringImplBridge.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/bridge/StringImplBridge.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,15 @@
+//$Id: $
+package org.hibernate.lucene.bridge;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class StringImplBridge implements StringBridge {
+ public Object stringToObject(String stringValue) {
+ return stringValue;
+ }
+
+ public String objectToString(Object object) {
+ return (String) object;
+ }
+}
Modified: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/event/LuceneEventListener.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -41,10 +41,17 @@
* @author Emmanuel Bernard
* @author Mattias Arbin
*/
-//TODO takes care of synchronization and index concurrent index change
+//TODO work on sharing the same indexWriters and readers across a single post operation...
public class LuceneEventListener implements PostDeleteEventListener, PostInsertEventListener,
PostUpdateEventListener, Initializable {
+ //FIXME keeping this here is a bad decision since you might want to search indexes wo maintain it
+ @Deprecated
+ public Map<Class, DocumentBuilder<Object>> getDocumentBuilders() {
+ return documentBuilders;
+ }
+
+
private Map<Class, DocumentBuilder<Object>> documentBuilders = new HashMap<Class, DocumentBuilder<Object>>();
//** keep track of the index modifiers per file since 1 index modifier can be present at a time */
private Map<DirectoryProvider, Lock> indexLock = new HashMap<DirectoryProvider, Lock>();
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/EntityInfo.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/EntityInfo.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/EntityInfo.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,12 @@
+//$Id: $
+package org.hibernate.lucene.query;
+
+import java.io.Serializable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class EntityInfo {
+ public Class clazz;
+ public Serializable id;
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/IteratorImpl.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/IteratorImpl.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/IteratorImpl.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,38 @@
+//$Id: $
+package org.hibernate.lucene.query;
+
+import java.util.Iterator;
+
+import org.hibernate.Session;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IteratorImpl implements Iterator {
+
+ private final EntityInfo[] entityInfos;
+ private final Session session;
+ private int index = 0;
+ private final int size;
+
+ public IteratorImpl(EntityInfo[] entityInfos, Session session) {
+ this.entityInfos = entityInfos;
+ this.session = session;
+ this.size = entityInfos.length;
+ }
+
+ public boolean hasNext() {
+ return index < size;
+ }
+
+ public Object next() {
+ Object object = session.get( entityInfos[index].clazz, entityInfos[index].id );
+ index++;
+ return object;
+ }
+
+ public void remove() {
+ //TODO this is theorically doable
+ throw new UnsupportedOperationException( "Cannot remove from a lucene query interator" );
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/LuceneQueryImpl.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/LuceneQueryImpl.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/LuceneQueryImpl.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,258 @@
+//$Id: $
+package org.hibernate.lucene.query;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MultiSearcher;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.store.Directory;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.ParameterMetadata;
+import org.hibernate.event.PostInsertEventListener;
+import org.hibernate.impl.AbstractQueryImpl;
+import org.hibernate.lucene.DocumentBuilder;
+import org.hibernate.lucene.event.LuceneEventListener;
+
+/**
+ * @author Emmanuel Bernard
+ */
+//implements setParameter()
+public class LuceneQueryImpl extends AbstractQueryImpl {
+ private static final Log log = LogFactory.getLog( LuceneQueryImpl.class );
+ private org.apache.lucene.search.Query luceneQuery;
+ private Class[] classes;
+ private Integer firstResult;
+ private Integer maxResults;
+ private int resultSize;
+
+ /** classes must be immutable */
+ public LuceneQueryImpl(org.apache.lucene.search.Query query, Class[] classes, SessionImplementor session, ParameterMetadata parameterMetadata) {
+ //TODO handle flushMode
+ super( query.toString(), null, session, parameterMetadata );
+ this.luceneQuery = query;
+ this.classes = classes;
+ }
+
+ /**
+ * Return an interator on the results.
+ * Retrieve the object one by one (initialize it during the next() operation)
+ */
+ public Iterator iterate() throws HibernateException {
+ //implement an interator which keep the id/class for each hit and get the object on demand
+ //cause I can't keep the searcher and hence the hit opened. I dont have any hook to know when the
+ //user stop using it
+ //scrollable is better in this area
+
+ LuceneEventListener listener = getLuceneEventListener();
+ //find the directories
+ Searcher searcher = buildSearcher( listener );
+ Hits hits;
+ try {
+ hits = searcher.search( luceneQuery );
+ setResultSize(hits);
+ int first = first();
+ int max = max( first, hits );
+ EntityInfo[] entityInfos = new EntityInfo[max - first + 1];
+ for (int index = first ; index <= max ; index++ ) {
+ Document document = hits.doc( index );
+ EntityInfo entityInfo = new EntityInfo();
+ entityInfo.clazz = DocumentBuilder.getDocumentClass( document );
+ //FIXME should check that clazz match classes but this complexify a lot the firstResult/maxResult
+ entityInfo.id = DocumentBuilder.getDocumentId( listener, entityInfo.clazz, document );
+ entityInfos[ index - first ] = entityInfo;
+ }
+ return new IteratorImpl( entityInfos, (Session) this.session );
+ }
+ catch (IOException e) {
+ throw new HibernateException("Unable to query Lucene index", e);
+ }
+ finally {
+ if (searcher != null) try {
+ searcher.close();
+ }
+ catch (IOException e) {
+ log.warn( "Unable to properly close searcher during lucene query: " + getQueryString(), e );
+ }
+ }
+ }
+
+ public ScrollableResults scroll() throws HibernateException {
+ //keep the searcher open until the resultset is closed
+ LuceneEventListener listener = getLuceneEventListener();
+ //find the directories
+ Searcher searcher = buildSearcher( listener );
+ Hits hits;
+ try {
+ hits = searcher.search( luceneQuery );
+ setResultSize(hits);
+ int first = first();
+ int max = max( first, hits );
+ return new ScrollableResultsImpl( searcher, hits, first, max, (Session) this.session, listener );
+ }
+ catch (IOException e) {
+ try {
+ if ( searcher != null ) searcher.close();
+ }
+ catch (IOException ee) {
+ //we have the initial issue already
+ }
+ throw new HibernateException("Unable to query Lucene index", e);
+ }
+ }
+
+ public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
+ //TODO think about this scrollmode
+ return scroll();
+ }
+
+ public List list() throws HibernateException {
+ LuceneEventListener listener = getLuceneEventListener();
+ //find the directories
+ Searcher searcher = buildSearcher( listener );
+ Hits hits;
+ try {
+ hits = searcher.search( luceneQuery );
+ setResultSize(hits);
+ int first = first();
+ int max = max( first, hits );
+ List result = new ArrayList( max - first + 1);
+ Session sess = (Session) this.session;
+ for (int index = first ; index <= max ; index++ ) {
+ Document document = hits.doc( index );
+ Class clazz = DocumentBuilder.getDocumentClass( document );
+ //FIXME should check that clazz match classes but this complexify a lot the firstResult/maxResult
+ Serializable id = DocumentBuilder.getDocumentId( listener, clazz, document );
+ result.add( sess.load( clazz, id ) );
+ //use load to benefit from the batch-size (but facing some proxy casting issues...
+ }
+ //then initialize the objects
+ for (Object element : result) {
+ Hibernate.initialize(element);
+ }
+ return result;
+ }
+ catch (IOException e) {
+ throw new HibernateException("Unable to query Lucene index", e);
+ }
+ finally {
+ if (searcher != null) try {
+ searcher.close();
+ }
+ catch (IOException e) {
+ log.warn( "Unable to properly close searcher during lucene query: " + getQueryString(), e );
+ }
+ }
+ }
+
+ private int max(int first, Hits hits) {
+ return maxResults == null ?
+ first + hits.length() - 1 :
+ maxResults + first < hits.length() ?
+ first + maxResults :
+ hits.length() - 1;
+ }
+
+ private int first() {
+ return firstResult != null ? firstResult : 0;
+ }
+
+ private Searcher buildSearcher(LuceneEventListener listener) {
+ Map<Class, DocumentBuilder<Object>> builders = listener.getDocumentBuilders();
+ Set<Directory> directories = new HashSet<Directory>();
+ for (Class clazz : classes) {
+ DocumentBuilder builder = builders.get(clazz);
+ if (builder == null) throw new HibernateException( "Not a mapped entity: " + clazz);
+ directories.add( builder.getDirectoryProvider().getDirectory() );
+ }
+
+ //set up the searcher
+ Searcher searcher;
+ int dirNbr = directories.size();
+ if (dirNbr > 1) {
+ try {
+ IndexSearcher[] searchers = new IndexSearcher[ dirNbr ];
+ Iterator<Directory> it = directories.iterator();
+ for (int index = 0 ; index < dirNbr ; index++) {
+ searchers[index] = new IndexSearcher( it.next() );
+ }
+ searcher = new MultiSearcher(searchers);
+ }
+ catch(IOException e) {
+ throw new HibernateException("Unable to read Lucene directory", e);
+ }
+ }
+ else {
+ try {
+ searcher = new IndexSearcher( directories.iterator().next() );
+ }
+ catch (IOException e) {
+ throw new HibernateException("Unable to read Lucene directory", e);
+ }
+ }
+ return searcher;
+ }
+
+ private void setResultSize(Hits hits) {
+ resultSize = hits.length();
+ }
+
+ //FIXME does it make sense
+ public int resultSize() {
+ return this.resultSize;
+ }
+
+ public Query setFirstResult(int firstResult) {
+ this.firstResult = firstResult;
+ return this;
+ }
+
+ public Query setMaxResults(int maxResults) {
+ this.maxResults = maxResults;
+ return this;
+ }
+
+ private LuceneEventListener getLuceneEventListener() {
+ PostInsertEventListener[] listeners = session.getListeners().getPostCommitInsertEventListeners();
+ LuceneEventListener listener = null;
+ //FIXME this sucks since we mandante the event listener use
+ for(PostInsertEventListener candidate : listeners ) {
+ if (candidate instanceof LuceneEventListener) {
+ listener = (LuceneEventListener) candidate;
+ break;
+ }
+ }
+ if (listener == null) throw new HibernateException("Lucene event listener not initialized");
+ return listener;
+ }
+
+ public int executeUpdate() throws HibernateException {
+ throw new HibernateException( "Not supported operation" );
+ }
+
+ public Query setLockMode(String alias, LockMode lockMode) {
+ return null;
+ }
+
+ protected Map getLockModes() {
+ return null;
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/ScrollableResultsImpl.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/ScrollableResultsImpl.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/query/ScrollableResultsImpl.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,217 @@
+//$Id: $
+package org.hibernate.lucene.query;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.Searcher;
+import org.hibernate.HibernateException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.lucene.DocumentBuilder;
+import org.hibernate.lucene.event.LuceneEventListener;
+import org.hibernate.type.Type;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ScrollableResultsImpl implements ScrollableResults {
+ private final Searcher searcher;
+ private final Hits hits;
+ private final int first;
+ private final int max;
+ private int current;
+ private final Session session;
+ private final LuceneEventListener listener;
+ private EntityInfo[] entityInfos;
+
+ public ScrollableResultsImpl(
+ Searcher searcher, Hits hits, int first, int max, Session session, LuceneEventListener listener
+ ) {
+ this.searcher = searcher;
+ this.hits = hits;
+ this.first = first;
+ this.max = max;
+ this.current = first;
+ this.session = session;
+ this.listener = listener;
+ entityInfos = new EntityInfo[max - first + 1];
+ }
+ public boolean next() throws HibernateException {
+ return ++current <= max;
+ }
+
+ public boolean previous() throws HibernateException {
+ return --current >= first;
+ }
+
+ public boolean scroll(int i) throws HibernateException {
+ current = current + i;
+ return current >= first && current <= max;
+ }
+
+ public boolean last() throws HibernateException {
+ current = max;
+ return max >= first;
+ }
+
+ public boolean first() throws HibernateException {
+ current = first;
+ return max >= first;
+ }
+
+ public void beforeFirst() throws HibernateException {
+ current = first - 1;
+ }
+
+ public void afterLast() throws HibernateException {
+ current = max + 1;
+ }
+
+ public boolean isFirst() throws HibernateException {
+ return current == first;
+ }
+
+ public boolean isLast() throws HibernateException {
+ return current == max;
+ }
+
+ public void close() throws HibernateException {
+ try {
+ searcher.close();
+ }
+ catch (IOException e) {
+ throw new HibernateException( "Unable to close Lucene searcher", e);
+ }
+ }
+
+ public Object[] get() throws HibernateException {
+ if (current < first || current > max) return null; //or exception?
+ EntityInfo info = entityInfos[current - first];
+ if ( info == null ) {
+ info = new EntityInfo();
+ Document document = null;
+ try {
+ document = hits.doc( current );
+ }
+ catch (IOException e) {
+ throw new HibernateException( "Unable to read Lucene hits[" + current + "]", e);
+ }
+ info.clazz = DocumentBuilder.getDocumentClass( document );
+ //FIXME should check that clazz match classes but this complexify a lot the firstResult/maxResult
+ info.id = DocumentBuilder.getDocumentId( listener, info.clazz, document );
+ entityInfos[current - first] = info;
+ }
+ return new Object[] {
+ session.get( info.clazz, info.id )
+ };
+ }
+
+ public Object get(int i) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Type getType(int i) {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Integer getInteger(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Long getLong(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Float getFloat(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Boolean getBoolean(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Double getDouble(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Short getShort(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Byte getByte(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Character getCharacter(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public byte[] getBinary(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public String getText(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Blob getBlob(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Clob getClob(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public String getString(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public BigDecimal getBigDecimal(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public BigInteger getBigInteger(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Date getDate(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Locale getLocale(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public Calendar getCalendar(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public TimeZone getTimeZone(int col) throws HibernateException {
+ throw new UnsupportedOperationException( "Lucene does not work on columns" );
+ }
+
+ public int getRowNumber() throws HibernateException {
+ if ( max < first ) return -1;
+ return current - first;
+ }
+
+ public boolean setRowNumber(int rowNumber) throws HibernateException {
+ if (rowNumber >= 0) {
+ current = first + rowNumber;
+ }
+ else {
+ current = max + rowNumber + 1; //max row start at -1
+ }
+ return current >= first && current <= max;
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/util/BinderHelper.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/util/BinderHelper.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/java/org/hibernate/lucene/util/BinderHelper.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,51 @@
+//$Id: $
+package org.hibernate.lucene.util;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Member;
+import java.lang.reflect.Field;
+import java.beans.Introspector;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class BinderHelper {
+
+ private BinderHelper() {}
+
+ public static String getAttributeName(Member member) {
+ return getAttributeName( member, null );
+ }
+ /**
+ * Get attribute name out of member unless overriden by <code>name</code>
+ */
+ //TODO move to reflection layer
+ public static String getAttributeName(Member member, String name) {
+ if( StringHelper.isNotEmpty( name ) ) return name; //explicit field name
+ if (member instanceof Field ) {
+ return ( (Field) member ).getName();
+ }
+ else {
+ //decapitalize
+ String methodName = ( (Method) member).getName();
+ //FIXME we probably should exclude methods not starting with "get" nor "is"
+ int startIndex = 3;
+ if( methodName.startsWith("is") ) {
+ startIndex = 2;
+ }
+ return Introspector.decapitalize( methodName.substring( startIndex ) );
+ }
+ }
+
+ //TODO move to reflection layer
+ public static Class<?> getReturnType(Member member) {
+ if (member instanceof Field) {
+ return ( (Field) member ).getType();
+ }
+ else {
+ return ( (Method) member ).getReturnType();
+ }
+ }
+}
Added: branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java
===================================================================
--- branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java 2006-07-13 01:52:08 UTC (rev 10113)
+++ branches/Lucene_Integration/HibernateExt/metadata/src/test/org/hibernate/lucene/test/Document.java 2006-07-13 02:16:13 UTC (rev 10114)
@@ -0,0 +1,72 @@
+//$Id: Document.java 10014 2006-06-12 09:56:27 -0700 (lun., 12 juin 2006) epbernard $
+package org.hibernate.lucene.test;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+
+import org.hibernate.lu...
[truncated message content] |