Hibernate SVN: r18166 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 11:32:59 -0500 (Tue, 08 Dec 2009)
New Revision: 18166
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
Log:
unwrap should raise a PE if the type is not unwrappable by the provider
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 16:16:27 UTC (rev 18165)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 16:32:59 UTC (rev 18166)
@@ -645,8 +645,10 @@
if ( clazz.equals( SessionImplementor.class ) ) {
return ( T ) getSession();
}
- //FIXME
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ else {
+ //unknown class type
+ throw new PersistenceException( "Hibernate cannot unwrap " + clazz);
+ }
}
private void joinTransaction(boolean ignoreNotJoining) {
15 years
Hibernate SVN: r18165 - in core/branches/envers-hibernate-3.3/src: main/java/org/hibernate/envers/synchronization/work and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-12-08 11:16:27 -0500 (Tue, 08 Dec 2009)
New Revision: 18165
Added:
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java
Modified:
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
Log:
svn merge -r 18150:18163 https://svn.jboss.org/repos/hibernate/core/trunk/envers .
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java 2009-12-08 16:09:42 UTC (rev 18164)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/GlobalConfiguration.java 2009-12-08 16:16:27 UTC (rev 18165)
@@ -74,8 +74,8 @@
"false");
storeDataAtDelete = Boolean.parseBoolean(storeDataDeletedEntityStr);
- defaultSchemaName = properties.getProperty("org.hibernate.envers.default_audit_table_schema_name", null);
- defaultCatalogName = properties.getProperty("org.hibernate.envers.default_audit_table_catalog_name", null);
+ defaultSchemaName = properties.getProperty("org.hibernate.envers.default_schema", null);
+ defaultCatalogName = properties.getProperty("org.hibernate.envers.default_catalog", null);
correlatedSubqueryOperator = "org.hibernate.dialect.HSQLDialect".equals(
properties.getProperty("hibernate.dialect")) ? "in" : "=";
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2009-12-08 16:09:42 UTC (rev 18164)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2009-12-08 16:16:27 UTC (rev 18165)
@@ -26,6 +26,8 @@
import java.io.Serializable;
import java.util.List;
import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
@@ -45,14 +47,14 @@
private final String referencingPropertyName;
public PersistentCollectionChangeWorkUnit(SessionImplementor sessionImplementor, String entityName,
- AuditConfiguration verCfg, PersistentCollection collection,
+ AuditConfiguration auditCfg, PersistentCollection collection,
CollectionEntry collectionEntry, Serializable snapshot, Serializable id) {
- super(sessionImplementor, entityName, verCfg, null);
+ super(sessionImplementor, entityName, auditCfg, new PersistentCollectionChangeWorkUnitId(id, collectionEntry.getRole()));
String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);
- collectionChanges = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper()
+ collectionChanges = auditCfg.getEntCfg().get(getEntityName()).getPropertyMapper()
.mapCollectionChanges(referencingPropertyName, collection, snapshot, id);
}
@@ -98,6 +100,82 @@
}
public KeepCheckResult dispatch(KeepCheckVisitor first) {
- return null;
+ if (first instanceof PersistentCollectionChangeWorkUnit) {
+ PersistentCollectionChangeWorkUnit original = (PersistentCollectionChangeWorkUnit) first;
+
+ // Merging the collection changes in both work units.
+
+ // First building a map from the ids of the collection-entry-entities from the "second" collection changes,
+ // to the PCCD objects. That way, we will be later able to check if an "original" collection change
+ // should be added, or if it is overshadowed by a new one.
+ Map<Object, PersistentCollectionChangeData> newChangesIdMap = new HashMap<Object, PersistentCollectionChangeData>();
+ for (PersistentCollectionChangeData persistentCollectionChangeData : getCollectionChanges()) {
+ newChangesIdMap.put(
+ getOriginalId(persistentCollectionChangeData),
+ persistentCollectionChangeData);
+ }
+
+ // Storing the current changes
+ List<PersistentCollectionChangeData> newChanges = new ArrayList<PersistentCollectionChangeData>();
+ newChanges.addAll(collectionChanges);
+
+ // And building the change list again
+ collectionChanges.clear();
+ for (PersistentCollectionChangeData originalCollectionChangeData : original.getCollectionChanges()) {
+ if (!newChangesIdMap.containsKey(getOriginalId(originalCollectionChangeData))) {
+ collectionChanges.add(originalCollectionChangeData);
+ }
+ }
+
+ // Finally adding all of the new changes to the end of the list
+ collectionChanges.addAll(newChanges);
+ } else {
+ throw new RuntimeException("Trying to merge a " + first + " with a PersitentCollectionChangeWorkUnit. " +
+ "This is not really possible.");
+ }
+
+ return KeepCheckResult.SECOND;
}
+
+ private Object getOriginalId(PersistentCollectionChangeData persistentCollectionChangeData) {
+ return persistentCollectionChangeData.getData().get(verCfg.getAuditEntCfg().getOriginalIdPropName());
+ }
+
+ /**
+ * A unique identifier for a collection work unit. Consists of an id of the owning entity and the name of
+ * the entity plus the name of the field (the role). This is needed because such collections aren't entities
+ * in the "normal" mapping, but they are entities for Envers.
+ */
+ private static class PersistentCollectionChangeWorkUnitId implements Serializable {
+ private static final long serialVersionUID = -8007831518629167537L;
+
+ private final Serializable ownerId;
+ private final String role;
+
+ public PersistentCollectionChangeWorkUnitId(Serializable ownerId, String role) {
+ this.ownerId = ownerId;
+ this.role = role;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PersistentCollectionChangeWorkUnitId that = (PersistentCollectionChangeWorkUnitId) o;
+
+ if (ownerId != null ? !ownerId.equals(that.ownerId) : that.ownerId != null) return false;
+ //noinspection RedundantIfStatement
+ if (role != null ? !role.equals(that.role) : that.role != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ownerId != null ? ownerId.hashCode() : 0;
+ result = 31 * result + (role != null ? role.hashCode() : 0);
+ return result;
+ }
+ }
}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java (from rev 18163, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java 2009-12-08 16:16:27 UTC (rev 18165)
@@ -0,0 +1,144 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.manytomany.ternary;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.IntTestEntity;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.hibernate.envers.test.tools.TestTools;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+import javax.persistence.EntityManager;
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class TernaryMapFlush extends AbstractEntityTest {
+ private Integer str1_id;
+ private Integer str2_id;
+ private Integer int1_id;
+ private Integer int2_id;
+ private Integer map1_id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(TernaryMapEntity.class);
+ cfg.addAnnotatedClass(StrTestEntity.class);
+ cfg.addAnnotatedClass(IntTestEntity.class);
+ }
+
+ @Test
+ public void createData() {
+ EntityManager em = getEntityManager();
+
+ StrTestEntity str1 = new StrTestEntity("a");
+ StrTestEntity str2 = new StrTestEntity("b");
+ IntTestEntity int1 = new IntTestEntity(1);
+ IntTestEntity int2 = new IntTestEntity(2);
+ TernaryMapEntity map1 = new TernaryMapEntity();
+
+ // Revision 1 (int1 -> str1)
+ em.getTransaction().begin();
+
+ em.persist(str1);
+ em.persist(str2);
+ em.persist(int1);
+ em.persist(int2);
+
+ map1.getMap().put(int1, str1);
+
+ em.persist(map1);
+
+ em.getTransaction().commit();
+
+ // Revision 2 (removing int1->str1, flushing, adding int1->str1 again and a new int2->str2 mapping to force a change)
+
+ em.getTransaction().begin();
+
+ map1 = em.find(TernaryMapEntity.class, map1.getId());
+ str1 = em.find(StrTestEntity.class, str1.getId());
+ int1 = em.find(IntTestEntity.class, int1.getId());
+
+ map1.setMap(new HashMap<IntTestEntity, StrTestEntity>());
+
+ em.flush();
+
+ map1.getMap().put(int1, str1);
+ map1.getMap().put(int2, str2);
+
+ em.getTransaction().commit();
+
+ // Revision 3 (removing int1->str1, flushing, overwriting int2->str1)
+
+ em.getTransaction().begin();
+
+ map1 = em.find(TernaryMapEntity.class, map1.getId());
+ str1 = em.find(StrTestEntity.class, str1.getId());
+ int1 = em.find(IntTestEntity.class, int1.getId());
+
+ map1.getMap().remove(int1);
+
+ em.flush();
+
+ map1.getMap().put(int2, str1);
+
+ em.getTransaction().commit();
+
+ //
+
+ map1_id = map1.getId();
+ str1_id = str1.getId();
+ str2_id = str2.getId();
+ int1_id = int1.getId();
+ int2_id = int2.getId();
+ }
+
+ @Test(dependsOnMethods = "createData")
+ public void testRevisionsCounts() {
+ assertEquals(Arrays.asList(1, 2, 3), getAuditReader().getRevisions(TernaryMapEntity.class, map1_id));
+ assertEquals(Arrays.asList(1), getAuditReader().getRevisions(StrTestEntity.class, str1_id));
+ assertEquals(Arrays.asList(1), getAuditReader().getRevisions(StrTestEntity.class, str2_id));
+ assertEquals(Arrays.asList(1) ,getAuditReader().getRevisions(IntTestEntity.class, int1_id));
+ assertEquals(Arrays.asList(1) ,getAuditReader().getRevisions(IntTestEntity.class, int2_id));
+ }
+
+ @Test(dependsOnMethods = "createData")
+ public void testHistoryOfMap1() {
+ StrTestEntity str1 = getEntityManager().find(StrTestEntity.class, str1_id);
+ StrTestEntity str2 = getEntityManager().find(StrTestEntity.class, str2_id);
+ IntTestEntity int1 = getEntityManager().find(IntTestEntity.class, int1_id);
+ IntTestEntity int2 = getEntityManager().find(IntTestEntity.class, int2_id);
+
+ TernaryMapEntity rev1 = getAuditReader().find(TernaryMapEntity.class, map1_id, 1);
+ TernaryMapEntity rev2 = getAuditReader().find(TernaryMapEntity.class, map1_id, 2);
+ TernaryMapEntity rev3 = getAuditReader().find(TernaryMapEntity.class, map1_id, 3);
+
+ assertEquals(rev1.getMap(), TestTools.makeMap(int1, str1));
+ assertEquals(rev2.getMap(), TestTools.makeMap(int1, str1, int2, str2));
+ assertEquals(rev3.getMap(), TestTools.makeMap(int2, str1));
+ }
+}
\ No newline at end of file
15 years
Hibernate SVN: r18164 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 11:09:42 -0500 (Tue, 08 Dec 2009)
New Revision: 18164
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
Log:
remove getSupportedProperties(): it's no longer part of the spec
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 16:08:13 UTC (rev 18163)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 16:09:42 UTC (rev 18164)
@@ -400,11 +400,6 @@
return null; //To change body of implemented methods use File | Settings | File Templates.
}
- public Set<String> getSupportedProperties() {
- //FIXME
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
public void flush() {
try {
if ( !isTransactionInProgress() ) {
15 years
Hibernate SVN: r18163 - in core/trunk/envers/src: test/java/org/hibernate/envers/test/integration/manytomany/ternary and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-12-08 11:08:13 -0500 (Tue, 08 Dec 2009)
New Revision: 18163
Added:
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
Log:
HHH-4650:
- fix for removing an item from a persistent collection, flushing, and adding the same item again: merging the collection change work units data
- test
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2009-12-08 16:01:36 UTC (rev 18162)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/synchronization/work/PersistentCollectionChangeWorkUnit.java 2009-12-08 16:08:13 UTC (rev 18163)
@@ -26,6 +26,8 @@
import java.io.Serializable;
import java.util.List;
import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.envers.configuration.AuditEntitiesConfiguration;
@@ -45,14 +47,14 @@
private final String referencingPropertyName;
public PersistentCollectionChangeWorkUnit(SessionImplementor sessionImplementor, String entityName,
- AuditConfiguration verCfg, PersistentCollection collection,
+ AuditConfiguration auditCfg, PersistentCollection collection,
CollectionEntry collectionEntry, Serializable snapshot, Serializable id) {
- super(sessionImplementor, entityName, verCfg, null);
+ super(sessionImplementor, entityName, auditCfg, new PersistentCollectionChangeWorkUnitId(id, collectionEntry.getRole()));
String ownerEntityName = ((AbstractCollectionPersister) collectionEntry.getLoadedPersister()).getOwnerEntityName();
referencingPropertyName = collectionEntry.getRole().substring(ownerEntityName.length() + 1);
- collectionChanges = verCfg.getEntCfg().get(getEntityName()).getPropertyMapper()
+ collectionChanges = auditCfg.getEntCfg().get(getEntityName()).getPropertyMapper()
.mapCollectionChanges(referencingPropertyName, collection, snapshot, id);
}
@@ -98,6 +100,82 @@
}
public KeepCheckResult dispatch(KeepCheckVisitor first) {
- return null;
+ if (first instanceof PersistentCollectionChangeWorkUnit) {
+ PersistentCollectionChangeWorkUnit original = (PersistentCollectionChangeWorkUnit) first;
+
+ // Merging the collection changes in both work units.
+
+ // First building a map from the ids of the collection-entry-entities from the "second" collection changes,
+ // to the PCCD objects. That way, we will be later able to check if an "original" collection change
+ // should be added, or if it is overshadowed by a new one.
+ Map<Object, PersistentCollectionChangeData> newChangesIdMap = new HashMap<Object, PersistentCollectionChangeData>();
+ for (PersistentCollectionChangeData persistentCollectionChangeData : getCollectionChanges()) {
+ newChangesIdMap.put(
+ getOriginalId(persistentCollectionChangeData),
+ persistentCollectionChangeData);
+ }
+
+ // Storing the current changes
+ List<PersistentCollectionChangeData> newChanges = new ArrayList<PersistentCollectionChangeData>();
+ newChanges.addAll(collectionChanges);
+
+ // And building the change list again
+ collectionChanges.clear();
+ for (PersistentCollectionChangeData originalCollectionChangeData : original.getCollectionChanges()) {
+ if (!newChangesIdMap.containsKey(getOriginalId(originalCollectionChangeData))) {
+ collectionChanges.add(originalCollectionChangeData);
+ }
+ }
+
+ // Finally adding all of the new changes to the end of the list
+ collectionChanges.addAll(newChanges);
+ } else {
+ throw new RuntimeException("Trying to merge a " + first + " with a PersitentCollectionChangeWorkUnit. " +
+ "This is not really possible.");
+ }
+
+ return KeepCheckResult.SECOND;
}
+
+ private Object getOriginalId(PersistentCollectionChangeData persistentCollectionChangeData) {
+ return persistentCollectionChangeData.getData().get(verCfg.getAuditEntCfg().getOriginalIdPropName());
+ }
+
+ /**
+ * A unique identifier for a collection work unit. Consists of an id of the owning entity and the name of
+ * the entity plus the name of the field (the role). This is needed because such collections aren't entities
+ * in the "normal" mapping, but they are entities for Envers.
+ */
+ private static class PersistentCollectionChangeWorkUnitId implements Serializable {
+ private static final long serialVersionUID = -8007831518629167537L;
+
+ private final Serializable ownerId;
+ private final String role;
+
+ public PersistentCollectionChangeWorkUnitId(Serializable ownerId, String role) {
+ this.ownerId = ownerId;
+ this.role = role;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PersistentCollectionChangeWorkUnitId that = (PersistentCollectionChangeWorkUnitId) o;
+
+ if (ownerId != null ? !ownerId.equals(that.ownerId) : that.ownerId != null) return false;
+ //noinspection RedundantIfStatement
+ if (role != null ? !role.equals(that.role) : that.role != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = ownerId != null ? ownerId.hashCode() : 0;
+ result = 31 * result + (role != null ? role.hashCode() : 0);
+ return result;
+ }
+ }
}
Copied: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java (from rev 18113, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMap.java)
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/manytomany/ternary/TernaryMapFlush.java 2009-12-08 16:08:13 UTC (rev 18163)
@@ -0,0 +1,144 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.envers.test.integration.manytomany.ternary;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.IntTestEntity;
+import org.hibernate.envers.test.entities.StrTestEntity;
+import org.hibernate.envers.test.tools.TestTools;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+import javax.persistence.EntityManager;
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * @author Adam Warski (adam at warski dot org)
+ */
+public class TernaryMapFlush extends AbstractEntityTest {
+ private Integer str1_id;
+ private Integer str2_id;
+ private Integer int1_id;
+ private Integer int2_id;
+ private Integer map1_id;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(TernaryMapEntity.class);
+ cfg.addAnnotatedClass(StrTestEntity.class);
+ cfg.addAnnotatedClass(IntTestEntity.class);
+ }
+
+ @Test
+ public void createData() {
+ EntityManager em = getEntityManager();
+
+ StrTestEntity str1 = new StrTestEntity("a");
+ StrTestEntity str2 = new StrTestEntity("b");
+ IntTestEntity int1 = new IntTestEntity(1);
+ IntTestEntity int2 = new IntTestEntity(2);
+ TernaryMapEntity map1 = new TernaryMapEntity();
+
+ // Revision 1 (int1 -> str1)
+ em.getTransaction().begin();
+
+ em.persist(str1);
+ em.persist(str2);
+ em.persist(int1);
+ em.persist(int2);
+
+ map1.getMap().put(int1, str1);
+
+ em.persist(map1);
+
+ em.getTransaction().commit();
+
+ // Revision 2 (removing int1->str1, flushing, adding int1->str1 again and a new int2->str2 mapping to force a change)
+
+ em.getTransaction().begin();
+
+ map1 = em.find(TernaryMapEntity.class, map1.getId());
+ str1 = em.find(StrTestEntity.class, str1.getId());
+ int1 = em.find(IntTestEntity.class, int1.getId());
+
+ map1.setMap(new HashMap<IntTestEntity, StrTestEntity>());
+
+ em.flush();
+
+ map1.getMap().put(int1, str1);
+ map1.getMap().put(int2, str2);
+
+ em.getTransaction().commit();
+
+ // Revision 3 (removing int1->str1, flushing, overwriting int2->str1)
+
+ em.getTransaction().begin();
+
+ map1 = em.find(TernaryMapEntity.class, map1.getId());
+ str1 = em.find(StrTestEntity.class, str1.getId());
+ int1 = em.find(IntTestEntity.class, int1.getId());
+
+ map1.getMap().remove(int1);
+
+ em.flush();
+
+ map1.getMap().put(int2, str1);
+
+ em.getTransaction().commit();
+
+ //
+
+ map1_id = map1.getId();
+ str1_id = str1.getId();
+ str2_id = str2.getId();
+ int1_id = int1.getId();
+ int2_id = int2.getId();
+ }
+
+ @Test(dependsOnMethods = "createData")
+ public void testRevisionsCounts() {
+ assertEquals(Arrays.asList(1, 2, 3), getAuditReader().getRevisions(TernaryMapEntity.class, map1_id));
+ assertEquals(Arrays.asList(1), getAuditReader().getRevisions(StrTestEntity.class, str1_id));
+ assertEquals(Arrays.asList(1), getAuditReader().getRevisions(StrTestEntity.class, str2_id));
+ assertEquals(Arrays.asList(1) ,getAuditReader().getRevisions(IntTestEntity.class, int1_id));
+ assertEquals(Arrays.asList(1) ,getAuditReader().getRevisions(IntTestEntity.class, int2_id));
+ }
+
+ @Test(dependsOnMethods = "createData")
+ public void testHistoryOfMap1() {
+ StrTestEntity str1 = getEntityManager().find(StrTestEntity.class, str1_id);
+ StrTestEntity str2 = getEntityManager().find(StrTestEntity.class, str2_id);
+ IntTestEntity int1 = getEntityManager().find(IntTestEntity.class, int1_id);
+ IntTestEntity int2 = getEntityManager().find(IntTestEntity.class, int2_id);
+
+ TernaryMapEntity rev1 = getAuditReader().find(TernaryMapEntity.class, map1_id, 1);
+ TernaryMapEntity rev2 = getAuditReader().find(TernaryMapEntity.class, map1_id, 2);
+ TernaryMapEntity rev3 = getAuditReader().find(TernaryMapEntity.class, map1_id, 3);
+
+ assertEquals(rev1.getMap(), TestTools.makeMap(int1, str1));
+ assertEquals(rev2.getMap(), TestTools.makeMap(int1, str1, int2, str2));
+ assertEquals(rev3.getMap(), TestTools.makeMap(int2, str1));
+ }
+}
\ No newline at end of file
15 years
Hibernate SVN: r18162 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 11:01:36 -0500 (Tue, 08 Dec 2009)
New Revision: 18162
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
Log:
Bind Hibernate Core deprecated lock modes for completeness and map UPGRADE_NOWAIT like PESSIMISTIC_WRITE with a timeout of 0
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 15:40:12 UTC (rev 18161)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 16:01:36 UTC (rev 18162)
@@ -570,9 +570,13 @@
return LockModeType.OPTIMISTIC_FORCE_INCREMENT;
else if ( lockMode == LockMode.PESSIMISTIC_READ )
return LockModeType.PESSIMISTIC_READ;
- else if ( lockMode == LockMode.PESSIMISTIC_WRITE )
+ else if ( lockMode == LockMode.PESSIMISTIC_WRITE
+ || lockMode == LockMode.UPGRADE
+ || lockMode == LockMode.UPGRADE_NOWAIT) //timeout of 0
+ //TODO check that if we have UPGRADE_NOWAIT we have a timeout of zero?
return LockModeType.PESSIMISTIC_WRITE;
- else if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT )
+ else if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT
+ || lockMode == LockMode.FORCE)
return LockModeType.PESSIMISTIC_FORCE_INCREMENT;
throw new AssertionFailure("unhandled lock mode " + lockMode );
}
15 years
Hibernate SVN: r18161 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 10:40:12 -0500 (Tue, 08 Dec 2009)
New Revision: 18161
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
Log:
add a comment on flush mode
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 15:39:37 UTC (rev 18160)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java 2009-12-08 15:40:12 UTC (rev 18161)
@@ -492,6 +492,12 @@
}
}
+ /**
+ * Hibernate can be set in various flush modes that are unknown to
+ * JPA 2.0. This method can then return null.
+ * If it returns null, do em.unwrap(Session.class).getFlushMode() to get the
+ * Hibernate flush mode
+ */
public FlushModeType getFlushMode() {
FlushMode mode = getSession().getFlushMode();
if ( mode == FlushMode.AUTO ) {
@@ -501,7 +507,7 @@
this.flushModeType = FlushModeType.COMMIT;
}
else {
- return null; //TODO exception?
+ return null;
}
//otherwise this is an unknown mode for EJB3
return flushModeType;
15 years
Hibernate SVN: r18160 - core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 10:39:37 -0500 (Tue, 08 Dec 2009)
New Revision: 18160
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/NativeScanner.java
Log:
Remove System.err.println oops
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/NativeScanner.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/NativeScanner.java 2009-12-08 14:20:56 UTC (rev 18159)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/NativeScanner.java 2009-12-08 15:39:37 UTC (rev 18160)
@@ -160,7 +160,6 @@
for (String pattern : filePatterns) {
sb.append( " " ).append( pattern ).append( "\n" );
}
- System.err.println(sb.toString());
JarVisitor jarVisitor = getVisitor( jarToScan );
//state visitor available
15 years
Hibernate SVN: r18159 - in core/trunk: annotations/src/main/java/org/hibernate/cfg/annotations/reflection and 2 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 09:20:56 -0500 (Tue, 08 Dec 2009)
New Revision: 18159
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
Log:
HHH-4649 Properly bind Environment#GLOBALLY_QUOTED_IDENTIFIERS to orm.xml <delimited-identifier/>
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-12-08 13:14:47 UTC (rev 18158)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-12-08 14:20:56 UTC (rev 18159)
@@ -288,6 +288,12 @@
//process default values first
if ( !isDefaultProcessed ) {
+ //use global delimiters if orm.xml declare it
+ final Object isDelimited = reflectionManager.getDefaults().get( "delimited-identifier" );
+ if (isDelimited != null && isDelimited == Boolean.TRUE) {
+ getProperties().put( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
+ }
+
AnnotationBinder.bindDefaults( createExtendedMappings() );
isDefaultProcessed = true;
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java 2009-12-08 13:14:47 UTC (rev 18158)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java 2009-12-08 14:20:56 UTC (rev 18159)
@@ -48,6 +48,8 @@
if ( defaults == null ) {
defaults = new HashMap<Object, Object>();
XMLContext.Default xmlDefaults = xmlContext.getDefault( null );
+
+ defaults.put( "delimited-identifier", xmlDefaults.getDelimitedIdentifier() );
List<Class> entityListeners = new ArrayList<Class>();
for ( String className : xmlContext.getDefaultEntityListeners() ) {
try {
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java 2009-12-08 13:14:47 UTC (rev 18158)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java 2009-12-08 14:20:56 UTC (rev 18159)
@@ -73,6 +73,8 @@
globalDefaults.setAccess( unitElement != null ? unitElement.getTextTrim() : null );
unitElement = defaultElement.element( "cascade-persist" );
globalDefaults.setCascadePersist( unitElement != null ? Boolean.TRUE : null );
+ unitElement = defaultElement.element( "delimited-identifiers" );
+ globalDefaults.setDelimitedIdentifiers( unitElement != null ? Boolean.TRUE : null );
defaultEntityListeners.addAll( addEntityListenerClasses( defaultElement, null, addedClasses ) );
}
}
@@ -198,6 +200,7 @@
private String catalog;
private Boolean metadataComplete;
private Boolean cascadePersist;
+ private Boolean delimitedIdentifier;
public String getAccess() {
return access;
@@ -262,6 +265,7 @@
if ( globalDefault.getPackageName() != null ) packageName = globalDefault.getPackageName();
if ( globalDefault.getSchema() != null ) schema = globalDefault.getSchema();
if ( globalDefault.getCatalog() != null ) catalog = globalDefault.getCatalog();
+ if ( globalDefault.getDelimitedIdentifier() != null ) delimitedIdentifier = globalDefault.getDelimitedIdentifier();
if ( globalDefault.getMetadataComplete() != null ) {
metadataComplete = globalDefault.getMetadataComplete();
}
@@ -269,6 +273,14 @@
if ( globalDefault.getCascadePersist() != null ) cascadePersist = globalDefault.getCascadePersist();
}
}
+
+ public void setDelimitedIdentifiers(Boolean delimitedIdentifier) {
+ this.delimitedIdentifier = delimitedIdentifier;
+ }
+
+ public Boolean getDelimitedIdentifier() {
+ return delimitedIdentifier;
+ }
}
public List<String> getDefaultEntityListeners() {
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2009-12-08 13:14:47 UTC (rev 18158)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2009-12-08 14:20:56 UTC (rev 18159)
@@ -2803,6 +2803,8 @@
final class ObjectNameNormalizerImpl extends ObjectNameNormalizer implements Serializable {
public boolean isUseQuotedIdentifiersGlobally() {
+ //Do not cache this value as we lazily set it in Hibernate Annotation (AnnotationConfiguration)
+ //TODO use a dedicated protected useQuotedIdentifier flag in Configuration (overriden by AnnotationConfiguration)
String setting = (String) properties.get( Environment.GLOBALLY_QUOTED_IDENTIFIERS );
return setting != null && Boolean.valueOf( setting ).booleanValue();
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java 2009-12-08 13:14:47 UTC (rev 18158)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java 2009-12-08 14:20:56 UTC (rev 18159)
@@ -188,9 +188,6 @@
this.setProperty( Environment.DATASOURCE, metadata.getNonJtaDatasource() );
}
defineTransactionType( metadata.getTransactionType(), workingVars );
- if ( metadata.isUseQuotedIdentifiers() ) {
- this.setProperty( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
- }
if ( metadata.getClasses().size() > 0 ) {
workingVars.put( HibernatePersistence.CLASS_NAMES, metadata.getClasses() );
}
15 years
Hibernate SVN: r18158 - in core/trunk: annotations/src/main/java/org/hibernate/cfg/annotations and 5 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-12-08 08:14:47 -0500 (Tue, 08 Dec 2009)
New Revision: 18158
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
core/trunk/core/src/main/java/org/hibernate/LockOptions.java
core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java
core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceMetadata.java
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
Log:
HHH-4553 - Hibernate doesn't support official JPA2 escape char for table name
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -444,6 +444,9 @@
( (org.hibernate.mapping.Column) id.getColumnIterator().next() ).getName()
);
}
+ // YUCK! but cannot think of a clean way to do this given the string-config based scheme
+ params.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, mappings.getObjectNameNormalizer() );
+
if ( !isDefault( generatorName ) ) {
//we have a named generator
IdGenerator gen = mappings.getGenerator( generatorName, localGenerators );
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -189,9 +189,15 @@
}
protected void initMappingColumn(
- String columnName, String propertyName, int length, int precision, int scale, boolean nullable,
- String sqlType, boolean unique, boolean applyNamingStrategy
- ) {
+ String columnName,
+ String propertyName,
+ int length,
+ int precision,
+ int scale,
+ boolean nullable,
+ String sqlType,
+ boolean unique,
+ boolean applyNamingStrategy) {
if ( StringHelper.isNotEmpty( formulaString ) ) {
this.formula = new Formula();
this.formula.setFormula( formulaString );
@@ -218,16 +224,25 @@
if ( applyNamingStrategy ) {
if ( StringHelper.isEmpty( columnName ) ) {
if ( propertyName != null ) {
- mappingColumn.setName( mappings.getNamingStrategy().propertyToColumnName( propertyName ) );
+ mappingColumn.setName(
+ mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ mappings.getNamingStrategy().propertyToColumnName( propertyName )
+ )
+ );
}
//Do nothing otherwise
}
else {
- mappingColumn.setName( mappings.getNamingStrategy().columnName( columnName ) );
+ columnName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnName );
+ columnName = mappings.getNamingStrategy().columnName( columnName );
+ columnName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnName );
+ mappingColumn.setName( columnName );
}
}
else {
- if ( StringHelper.isNotEmpty( columnName ) ) mappingColumn.setName( columnName );
+ if ( StringHelper.isNotEmpty( columnName ) ) {
+ mappingColumn.setName( mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnName ) );
+ }
}
}
@@ -383,31 +398,38 @@
log.debug( "Column(s) overridden for property {}", inferredData.getPropertyName() );
}
if ( actualCols == null ) {
- columns = buildImplicitColumn( inferredData,
+ columns = buildImplicitColumn(
+ inferredData,
suffixForDefaultColumnName,
secondaryTables,
propertyHolder,
nullability,
- mappings );
+ mappings
+ );
}
else {
final int length = actualCols.length;
columns = new Ejb3Column[length];
for (int index = 0; index < length; index++) {
+ final ObjectNameNormalizer nameNormalizer = mappings.getObjectNameNormalizer();
javax.persistence.Column col = actualCols[index];
- String sqlType = col.columnDefinition().equals( "" ) ? null : col.columnDefinition();
+ final String sqlType = col.columnDefinition().equals( "" )
+ ? null
+ : nameNormalizer.normalizeIdentifierQuoting( col.columnDefinition() );
+ final String tableName = nameNormalizer.normalizeIdentifierQuoting( col.table() );
+ final String columnName = nameNormalizer.normalizeIdentifierQuoting( col.name() );
Ejb3Column column = new Ejb3Column();
column.setImplicit( false );
column.setSqlType( sqlType );
column.setLength( col.length() );
column.setPrecision( col.precision() );
column.setScale( col.scale() );
- column.setLogicalColumnName( col.name() );
- //support for explicit property name + suffix
- if ( StringHelper.isEmpty( column.getLogicalColumnName() )
- && ! StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
+ if ( StringHelper.isEmpty( columnName ) && ! StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
column.setLogicalColumnName( inferredData.getPropertyName() + suffixForDefaultColumnName );
}
+ else {
+ column.setLogicalColumnName( columnName );
+ }
column.setPropertyName(
BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
@@ -418,7 +440,7 @@
column.setUnique( col.unique() );
column.setInsertable( col.insertable() );
column.setUpdatable( col.updatable() );
- column.setSecondaryTableName( col.table() );
+ column.setSecondaryTableName( tableName );
column.setPropertyHolder( propertyHolder );
column.setJoins( secondaryTables );
column.setMappings( mappings );
@@ -436,12 +458,11 @@
Map<String, Join> secondaryTables,
PropertyHolder propertyHolder,
Nullability nullability,
- ExtendedMappings mappings
- ) {
- Ejb3Column[] columns;
- columns = new Ejb3Column[1];
+ ExtendedMappings mappings) {
Ejb3Column column = new Ejb3Column();
- column.setImplicit( false );
+ Ejb3Column[] columns = new Ejb3Column[1];
+ columns[0] = column;
+
//not following the spec but more clean
if ( nullability != Nullability.FORCED_NULL
&& inferredData.getClassOrElement().isPrimitive()
@@ -466,7 +487,6 @@
column.setImplicit( true );
}
column.bind();
- columns[0] = column;
return columns;
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -332,8 +332,14 @@
columnDefinition = joinAnn.columnDefinition();
referencedColumnName = joinAnn.referencedColumnName();
}
- String sqlType = "".equals( columnDefinition ) ? null : columnDefinition;
- String name = "".equals( colName ) ? defaultName : colName;
+
+ String sqlType = "".equals( columnDefinition )
+ ? null
+ : mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnDefinition );
+ String name = "".equals( colName )
+ ? defaultName
+ : colName;
+ name = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( name );
return new Ejb3JoinColumn(
sqlType,
name, false, false,
@@ -344,6 +350,7 @@
);
}
else {
+ defaultName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( defaultName );
return new Ejb3JoinColumn(
(String) null, defaultName,
false, false, true, true, null, (String) null,
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -48,7 +48,6 @@
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value;
-import org.hibernate.util.CollectionHelper;
import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -78,9 +77,8 @@
for (EntityResult entity : ann.entities()) {
//TODO parameterize lock mode?
- List properties = new ArrayList();
- List propertyNames = new ArrayList();
- Map propertyresults = new HashMap();
+ List<FieldResult> properties = new ArrayList<FieldResult>();
+ List<String> propertyNames = new ArrayList<String>();
for (FieldResult field : entity.fields()) {
//use an ArrayList cause we might have several columns per root property
String name = field.name();
@@ -120,18 +118,16 @@
}
}
- Set uniqueReturnProperty = new HashSet();
- Iterator iterator = properties.iterator();
- while ( iterator.hasNext() ) {
- FieldResult propertyresult = (FieldResult) iterator.next();
- String name = propertyresult.name();
+ Set<String> uniqueReturnProperty = new HashSet<String>();
+ Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
+ for ( Object property : properties ) {
+ final FieldResult propertyresult = ( FieldResult ) property;
+ final String name = propertyresult.name();
if ( "class".equals( name ) ) {
throw new MappingException(
"class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead"
);
}
- ArrayList allResultColumns = new ArrayList();
- allResultColumns.add( propertyresult.column() );
if ( uniqueReturnProperty.contains( name ) ) {
throw new MappingException(
@@ -140,38 +136,56 @@
);
}
uniqueReturnProperty.add( name );
+
+ final String quotingNormalizedColumnName = mappings.getObjectNameNormalizer()
+ .normalizeIdentifierQuoting( propertyresult.column() );
+
String key = StringHelper.root( name );
- ArrayList intermediateResults = (ArrayList) propertyresults.get( key );
+ ArrayList<String> intermediateResults = propertyResultsTmp.get( key );
if ( intermediateResults == null ) {
- propertyresults.put( key, allResultColumns );
+ intermediateResults = new ArrayList<String>();
+ propertyResultsTmp.put( key, intermediateResults );
}
- else {
- intermediateResults.addAll( allResultColumns );
- }
+ intermediateResults.add( quotingNormalizedColumnName );
}
- Iterator entries = propertyresults.entrySet().iterator();
- while ( entries.hasNext() ) {
- Map.Entry entry = (Map.Entry) entries.next();
- if ( entry.getValue() instanceof ArrayList ) {
- ArrayList list = (ArrayList) entry.getValue();
- entry.setValue( list.toArray( new String[list.size()] ) );
- }
+
+ Map<String, String[]> propertyResults = new HashMap<String,String[]>();
+ for ( Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet() ) {
+ propertyResults.put(
+ entry.getKey(),
+ entry.getValue().toArray( new String[ entry.getValue().size() ] )
+ );
}
if ( !BinderHelper.isDefault( entity.discriminatorColumn() ) ) {
- propertyresults.put( "class", new String[] { entity.discriminatorColumn() } );
+ final String quotingNormalizedName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ entity.discriminatorColumn()
+ );
+ propertyResults.put( "class", new String[] { quotingNormalizedName } );
}
- propertyresults = propertyresults.isEmpty() ? CollectionHelper.EMPTY_MAP : propertyresults;
- NativeSQLQueryRootReturn result =
- new NativeSQLQueryRootReturn(
- "alias" + entityAliasIndex++, entity.entityClass().getName(), propertyresults, LockMode.READ
- );
+ if ( propertyResults.isEmpty() ) {
+ propertyResults = java.util.Collections.emptyMap();
+ }
+
+ NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
+ "alias" + entityAliasIndex++,
+ entity.entityClass().getName(),
+ propertyResults,
+ LockMode.READ
+ );
definition.addQueryReturn( result );
}
- for (ColumnResult column : ann.columns()) {
- definition.addQueryReturn( new NativeSQLQueryScalarReturn( column.name(), null ) );
+ for ( ColumnResult column : ann.columns() ) {
+ definition.addQueryReturn(
+ new NativeSQLQueryScalarReturn(
+ mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ column.name()
+ ),
+ null
+ )
+ );
}
if ( isDefault ) {
@@ -182,6 +196,7 @@
}
}
+ @SuppressWarnings({ "unchecked" })
private List getFollowers(Iterator parentPropIter, String reducedName, String name) {
boolean hasFollowers = false;
List followers = new ArrayList();
Modified: core/trunk/core/src/main/java/org/hibernate/LockOptions.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/LockOptions.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/core/src/main/java/org/hibernate/LockOptions.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @author tags or express
+ * copyright attribution statements applied by the authors. All
+ * third-party contributions are distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate;
Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -2451,12 +2451,14 @@
String name,
String subselect,
boolean isAbstract) {
+ name = getObjectNameNormalizer().normalizeIdentifierQuoting( name );
+ schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
+ catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
+
String key = subselect == null ? Table.qualify( catalog, schema, name ) : subselect;
Table table = ( Table ) tables.get( key );
if ( table == null ) {
- schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
- catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
table = new Table();
table.setAbstract( isAbstract );
table.setName( name );
@@ -2481,14 +2483,15 @@
boolean isAbstract,
String subselect,
Table includedTable) throws DuplicateMappingException {
+ name = getObjectNameNormalizer().normalizeIdentifierQuoting( name );
+ schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
+ catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
+
String key = subselect == null ? Table.qualify(catalog, schema, name) : subselect;
if ( tables.containsKey( key ) ) {
throw new DuplicateMappingException( "table", name );
}
- schema = getObjectNameNormalizer().normalizeIdentifierQuoting( schema );
- catalog = getObjectNameNormalizer().normalizeIdentifierQuoting( catalog );
-
Table table = new DenormalizedTable( includedTable );
table.setAbstract( isAbstract );
table.setName( name );
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -100,8 +100,12 @@
public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
if ( isGenerated( dialect ) ) {
- return "alter table " + getTable()
- .getQualifiedName( dialect, defaultCatalog, defaultSchema ) + " drop constraint " + getName();
+ return new StringBuffer()
+ .append( "alter table " )
+ .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+ .append( " drop constraint " )
+ .append( dialect.quote( getName() ) )
+ .toString();
}
else {
return null;
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -39,22 +39,29 @@
public String sqlConstraintString(Dialect dialect) {
StringBuffer buf = new StringBuffer( "unique (" );
+ boolean hadNullableColumn = false;
Iterator iter = getColumnIterator();
- boolean nullable = false;
while ( iter.hasNext() ) {
Column column = (Column) iter.next();
- if ( !nullable && column.isNullable() ) nullable = true;
+ if ( !hadNullableColumn && column.isNullable() ) {
+ hadNullableColumn = true;
+ }
buf.append( column.getQuotedName( dialect ) );
- if ( iter.hasNext() ) buf.append( ", " );
+ if ( iter.hasNext() ) {
+ buf.append( ", " );
+ }
}
//do not add unique constraint on DB not supporting unique and nullable columns
- return !nullable || dialect.supportsNotNullUnique() ?
+ return !hadNullableColumn || dialect.supportsNotNullUnique() ?
buf.append( ')' ).toString() :
null;
}
- public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog,
- String defaultSchema) {
+ public String sqlConstraintString(
+ Dialect dialect,
+ String constraintName,
+ String defaultCatalog,
+ String defaultSchema) {
StringBuffer buf = new StringBuffer(
dialect.getAddPrimaryKeyConstraintString( constraintName )
).append( '(' );
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -188,6 +188,9 @@
this.setProperty( Environment.DATASOURCE, metadata.getNonJtaDatasource() );
}
defineTransactionType( metadata.getTransactionType(), workingVars );
+ if ( metadata.isUseQuotedIdentifiers() ) {
+ this.setProperty( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
+ }
if ( metadata.getClasses().size() > 0 ) {
workingVars.put( HibernatePersistence.CLASS_NAMES, metadata.getClasses() );
}
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceMetadata.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceMetadata.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceMetadata.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -43,6 +43,7 @@
private String jtaDatasource;
private String provider;
private PersistenceUnitTransactionType transactionType;
+ private boolean useQuotedIdentifiers = false; // the spec (erroneously?) calls this delimited-identifiers
private List<String> classes = new ArrayList<String>();
private List<String> packages = new ArrayList<String>();
private List<String> mappingFiles = new ArrayList<String>();
@@ -94,6 +95,14 @@
this.provider = provider;
}
+ public boolean isUseQuotedIdentifiers() {
+ return useQuotedIdentifiers;
+ }
+
+ public void setUseQuotedIdentifiers(boolean useQuotedIdentifiers) {
+ this.useQuotedIdentifiers = useQuotedIdentifiers;
+ }
+
public List<String> getClasses() {
return classes;
}
@@ -162,6 +171,7 @@
.append("\tnonJtaDataSource: ").append(nonJtaDatasource).append("\n")
.append("\ttransactionType: ").append(transactionType).append("\n")
.append("\tprovider: ").append(provider).append("\n")
+ .append("\tuseQuotedIdentifiers: ").append(useQuotedIdentifiers).append("\n")
.append("\tclasses[\n");
if (classes != null) {
for (String elt : classes) {
Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2009-12-08 11:19:42 UTC (rev 18157)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/packaging/PersistenceXmlLoader.java 2009-12-08 13:14:47 UTC (rev 18158)
@@ -209,6 +209,9 @@
else if ( tag.equals( "exclude-unlisted-classes" ) ) {
metadata.setExcludeUnlistedClasses( true );
}
+ else if ( tag.equals( "delimited-identifiers" ) ) {
+ metadata.setUseQuotedIdentifiers( true );
+ }
else if ( tag.equals( "properties" ) ) {
NodeList props = element.getChildNodes();
for ( int j = 0; j < props.getLength() ; j++ ) {
15 years
Hibernate SVN: r18157 - in search/trunk/src: main/java/org/hibernate/search and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2009-12-08 06:19:42 -0500 (Tue, 08 Dec 2009)
New Revision: 18157
Added:
search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java
search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java
Modified:
search/trunk/src/main/docbook/en-US/modules/mapping.xml
search/trunk/src/main/java/org/hibernate/search/Environment.java
search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
Log:
HSEARCH-429 Add Environment.MODEL_MAPPING (hibernate.search.model_mapping) to pass a SearchMapping configuration via configuration (Amin Mohammed-Coleman)
Modified: search/trunk/src/main/docbook/en-US/modules/mapping.xml
===================================================================
--- search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/docbook/en-US/modules/mapping.xml 2009-12-08 11:19:42 UTC (rev 18157)
@@ -1548,17 +1548,18 @@
<classname>SearchMapping</classname> object. This object is passed to
Hibernate Search via a property set to the <classname>Configuration
</classname>object. The property key is
- <literal>hibernate.search.mapping_model</literal>.</para>
+ <literal>hibernate.search.mapping_model</literal> or it's tpye-safe representation
+ <classname>Environment.MODEL_MAPPING</classname>.</para>
<programlisting>SearchMapping mapping = new SearchMapping();
[...]
-configuration.setProperty( "hibernate.search.mapping_model", mapping );
+configuration.setProperty( Environment.MODEL_MAPPING, mapping );
//or in JPA
SearchMapping mapping = new SearchMapping();
[...]
Map<String,String> properties = new HashMap<String,String)(1);
-properties.put( "hibernate.search.mapping_model", mapping );
+properties.put( Environment.MODEL_MAPPING, mapping );
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "userPU", properties );</programlisting>
<para>The <classname>SearchMapping</classname> is the root object which
@@ -1597,7 +1598,7 @@
.indexed()
.indexName("Address_Index"); //optional
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>As you can see you must first create a
<classname>SearchMapping</classname> object which is the root object
@@ -1637,7 +1638,7 @@
.documentId()
.name("id");
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping);</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping);</programlisting>
<para>The above is equivalent to annotating a property in the entity
as <classname>@DocumentId</classname> as seen in the following
@@ -1693,7 +1694,7 @@
.documentId()
.name("id");
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>The analyzer mapping defined above is equivalent to the
annotation model using <classname>@AnalyzerDef</classname> in
@@ -1772,7 +1773,7 @@
.analyzer("en")
.store(Store.NO);
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>The previous example can effectively been seen as annotating
your entity with <classname>@FullTextFilterDef</classname> like
@@ -1847,7 +1848,7 @@
.name("address_data")
.analyzer("en");</emphasis>
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>The above example of marking fields as indexable is equivalent
to defining fields using <classname>@Field</classname> as seen
@@ -1920,7 +1921,7 @@
<emphasis role="bold">.indexEmbedded()
.prefix("catalog.items"); //optional</emphasis>
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>The next example shows the same definition using annotation
(<classname>@IndexEmbedded</classname>):</para>
@@ -1980,7 +1981,7 @@
.property("productCatalog", ElementType.METHOD)
<emphasis role="bold">.containedIn()</emphasis>;
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>This is equivalent to defining
<classname>@ContainedIn</classname> in your entity:</para>
@@ -2061,7 +2062,7 @@
.property("lastUpdated", ElementType.FIELD)
<emphasis role="bold">.calendarBridge(Resolution.DAY)</emphasis>;
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>See below for defining the above using
<classname>@CalendarBridge</classname> and
@@ -2122,7 +2123,7 @@
<emphasis role="bold">.bridge( ConcatStringBridge.class )
.param( "size", "4" )</emphasis>;
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );</programlisting>
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );</programlisting>
<para>The above can equally be defined using annotations, as seen in
the next example.</para>
@@ -2182,7 +2183,7 @@
.param("3", "3Com")</emphasis>
.indexed();
-cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
+cfg.getProperties().put( "hibernate.search.model_mapping", mapping );
</programlisting>
Modified: search/trunk/src/main/java/org/hibernate/search/Environment.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/Environment.java 2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/Environment.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -110,5 +110,10 @@
* This is an index-scoped property and defaults to false.
*/
public static final String EXCLUSIVE_INDEX_USE = "exclusive_index_use";
+
+ /**
+ *
+ */
+ public static final String MODEL_MAPPING = "hibernate.search.model_mapping";
}
Modified: search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/cfg/SearchConfigurationFromHibernateCore.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -80,7 +80,7 @@
}
public SearchMapping getProgrammaticMapping() {
- return ( SearchMapping ) getProperties().get( "hibernate.search.mapping_model" );
+ return null;
}
private static class ClassIterator implements Iterator<Class<?>> {
Modified: search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/main/java/org/hibernate/search/impl/SearchFactoryImpl.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -27,6 +27,7 @@
import java.beans.Introspector;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -35,30 +36,26 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.Similarity;
-import org.slf4j.Logger;
-
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
-import org.hibernate.annotations.common.reflection.MetadataProvider;
-import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
-import org.hibernate.util.StringHelper;
import org.hibernate.search.Environment;
import org.hibernate.search.SearchException;
import org.hibernate.search.Version;
+import org.hibernate.search.annotations.AnalyzerDef;
+import org.hibernate.search.annotations.AnalyzerDefs;
import org.hibernate.search.annotations.Factory;
import org.hibernate.search.annotations.FullTextFilterDef;
import org.hibernate.search.annotations.FullTextFilterDefs;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Key;
-import org.hibernate.search.annotations.AnalyzerDef;
-import org.hibernate.search.annotations.AnalyzerDefs;
import org.hibernate.search.backend.BackendQueueProcessorFactory;
import org.hibernate.search.backend.LuceneIndexingParameters;
import org.hibernate.search.backend.LuceneWork;
@@ -72,11 +69,11 @@
import org.hibernate.search.batchindexing.MassIndexerProgressMonitor;
import org.hibernate.search.cfg.SearchConfiguration;
import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.engine.DocumentBuilderContainedEntity;
import org.hibernate.search.engine.DocumentBuilderIndexedEntity;
+import org.hibernate.search.engine.EntityState;
import org.hibernate.search.engine.FilterDef;
import org.hibernate.search.engine.SearchFactoryImplementor;
-import org.hibernate.search.engine.EntityState;
-import org.hibernate.search.engine.DocumentBuilderContainedEntity;
import org.hibernate.search.filter.CachingWrapperFilter;
import org.hibernate.search.filter.FilterCachingStrategy;
import org.hibernate.search.filter.MRUFilterCachingStrategy;
@@ -88,6 +85,8 @@
import org.hibernate.search.store.optimization.OptimizerStrategy;
import org.hibernate.search.util.LoggerFactory;
import org.hibernate.search.util.PluginLoader;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
/**
* @author Emmanuel Bernard
@@ -148,7 +147,18 @@
public SearchFactoryImpl(SearchConfiguration cfg) {
ReflectionManager reflectionManager = getReflectionManager(cfg);
-
+ final SearchMapping mapping = SearchMappingBuilder.getSearchMapping(cfg);
+ if ( mapping != null) {
+ if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
+ throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
+ + MetadataProviderInjector.class.getName() );
+ }
+ MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
+ MetadataProvider original = injector.getMetadataProvider();
+ injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
+
+ }
+
this.indexingStrategy = defineIndexingStrategy( cfg ); //need to be done before the document builds
initDocumentBuilders( cfg, reflectionManager );
@@ -171,6 +181,8 @@
this.barrier = 1; //write barrier
}
+
+
private void fillSimilarityMapping() {
for ( DirectoryProviderData directoryConfiguration : dirProviderData.values() ) {
for (Class<?> indexedType : directoryConfiguration.classes) {
@@ -194,17 +206,6 @@
if ( reflectionManager == null ) {
reflectionManager = new JavaReflectionManager();
}
- final SearchMapping mapping = cfg.getProgrammaticMapping();
- if ( mapping != null) {
- if ( ! ( reflectionManager instanceof MetadataProviderInjector)) {
- throw new SearchException("Programmatic mapping model used but ReflectionManager does not implement "
- + MetadataProviderInjector.class.getName() );
- }
- MetadataProviderInjector injector = (MetadataProviderInjector) reflectionManager;
- MetadataProvider original = injector.getMetadataProvider();
- injector.setMetadataProvider( new MappingModelMetadataProvider( original, mapping ) );
-
- }
return reflectionManager;
}
Added: search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java
===================================================================
--- search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java (rev 0)
+++ search/trunk/src/main/java/org/hibernate/search/impl/SearchMappingBuilder.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -0,0 +1,116 @@
+package org.hibernate.search.impl;
+
+import java.lang.reflect.Method;
+
+import org.hibernate.search.SearchException;
+import org.hibernate.search.Environment;
+import org.hibernate.search.cfg.SearchMapping;
+import org.hibernate.search.cfg.SearchConfiguration;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.annotations.common.util.ReflectHelper;
+
+import org.slf4j.Logger;
+
+/**
+ * package class extracting the SearchMappingFactory if needed
+ */
+class SearchMappingBuilder {
+ private static final Logger LOG = LoggerFactory.make();
+
+ private SearchMappingBuilder() {
+ }
+
+ /**
+ * This factory method takes a SearchConfiguration object
+ * and returns a SearchMapping object which defines
+ * the programmatic model for indexing entites and fields.
+ *
+ * Throws SearchException:
+ * 1) No @Factory found
+ * 2) Multiple @Factory found
+ * 3) hibernate.search.model_mapping defines a class that cannot be found
+ * 4) Cannot invoke the @Factory method to get new instance of SearchMapping
+ *
+ * @param SearchConfigruation
+ * @return SearchMapping
+ */
+ public static SearchMapping getSearchMapping(SearchConfiguration cfg) {
+
+ //try SearchConfiguration object first and then properties
+ Object modelMappingProperty = cfg.getProgrammaticMapping();
+ if ( modelMappingProperty == null) {
+ modelMappingProperty = cfg.getProperties().get( Environment.MODEL_MAPPING );
+ }
+
+ if ( modelMappingProperty == null) {
+ return null;
+ }
+ SearchMapping mapping = null;
+ Object programmaticConfig = modelMappingProperty;
+ if (programmaticConfig instanceof SearchMapping) {
+ mapping = (SearchMapping) programmaticConfig;
+ return mapping;
+ }
+ Class<?> clazz = getProgrammaticMappingClass(programmaticConfig);
+ Method[] methods = clazz.getDeclaredMethods();
+ int count = 0;
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(Factory.class)) {
+ count++;
+ makeMethodAccessibleIfRequired(method);
+ mapping = getNewInstanceOfSearchMapping(clazz, method);
+ }
+ }
+ validateMappingFactoryDefinition(count, clazz);
+ return mapping;
+ }
+
+ private static SearchMapping getNewInstanceOfSearchMapping(Class<?> clazz, Method method) {
+ SearchMapping mapping = null;
+ try {
+ LOG.debug("invoking factory method [ {}.{} ] to get search mapping instance", clazz.getName(), method.getName());
+ Object instance = clazz.newInstance();
+ mapping = (SearchMapping) method.invoke(instance);
+ } catch (Exception e) {
+ throw new SearchException("Unable to call the factory method: " + clazz.getName() + "." + method.getName(), e);
+ }
+ return mapping;
+ }
+
+ private static void makeMethodAccessibleIfRequired(Method method) {
+ if ( !method.isAccessible() ) {
+ method.setAccessible( true );
+ }
+ }
+
+ private static void validateMappingFactoryDefinition(int count, Class<?> factory) {
+ if (count == 0) {
+ throw new SearchException("No @Factory method defined for building programmatic api on " + factory);
+ }
+ if (count > 1) {
+ throw new SearchException("Multiple @Factory methods defined. Only one factory method required. " + factory);
+ }
+ }
+
+ private static Class<?> getProgrammaticMappingClass(Object programmaticConfig) {
+ Class<?> clazz = null;
+ if (programmaticConfig instanceof String) {
+ final String className = ( String ) programmaticConfig;
+ try {
+ clazz = ReflectHelper.classForName( className, SearchMappingBuilder.class);
+ } catch (ClassNotFoundException e) {
+ throw new SearchException("Unable to find " + Environment.MODEL_MAPPING + "=" + className, e);
+ }
+ } else if (programmaticConfig instanceof Class){
+ clazz = (Class<?>) programmaticConfig;
+ }
+ else {
+ throw new SearchException(Environment.MODEL_MAPPING + " is of an unknown type: " + programmaticConfig.getClass() );
+ }
+ if (clazz == null) {
+ throw new SearchException("No programmatic factory defined");
+ }
+ return clazz;
+ }
+}
Modified: search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-12-07 12:43:06 UTC (rev 18156)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticMappingTest.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -50,6 +50,7 @@
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
+import org.hibernate.search.Environment;
import org.hibernate.search.annotations.FilterCacheModeType;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Resolution;
@@ -634,104 +635,9 @@
@Override
protected void configure(Configuration cfg) {
super.configure( cfg );
+ cfg.getProperties().put( Environment.MODEL_MAPPING, ProgrammaticSearchMappingFactory.class.getName() );
//cfg.setProperty( "hibernate.search.default.directory_provider", FSDirectoryProvider.class.getName() );
- SearchMapping mapping = new SearchMapping();
- mapping.fullTextFilterDef("security", SecurityFilterFactory.class).cache(FilterCacheModeType.INSTANCE_ONLY)
- .analyzerDef( "ngram", StandardTokenizerFactory.class )
- .filter( LowerCaseFilterFactory.class )
- .filter( NGramFilterFactory.class )
- .param( "minGramSize", "3" )
- .param( "maxGramSize", "3" )
- .analyzerDef( "en", StandardTokenizerFactory.class )
- .filter( LowerCaseFilterFactory.class )
- .filter( EnglishPorterFilterFactory.class )
- .analyzerDef( "de", StandardTokenizerFactory.class )
- .filter( LowerCaseFilterFactory.class )
- .filter( GermanStemFilterFactory.class )
- .entity( Address.class )
- .indexed()
- .similarity( DefaultSimilarity.class )
- .boost( 2 )
- .property( "addressId", ElementType.FIELD ).documentId().name( "id" )
- .property("lastUpdated", ElementType.FIELD)
- .field().name("last-updated")
- .analyzer("en").store(Store.YES)
- .calendarBridge(Resolution.DAY)
- .property("dateCreated", ElementType.FIELD)
- .field().name("date-created").index(Index.TOKENIZED)
- .analyzer("en").store( Store.YES )
- .dateBridge(Resolution.DAY)
- .property("owner", ElementType.FIELD)
- .field()
- .property( "street1", ElementType.FIELD )
- .field()
- .field().name( "street1_ngram" ).analyzer( "ngram" )
- .field()
- .name( "street1_abridged" )
- .bridge( ConcatStringBridge.class ).param( ConcatStringBridge.SIZE, "4" )
- .property( "street2", ElementType.METHOD )
- .field().name( "idx_street2" ).store( Store.YES ).boost( 2 )
- .entity(ProvidedIdEntry.class).indexed()
- .providedId().name("providedidentry").bridge(LongBridge.class)
- .property("name", ElementType.FIELD)
- .field().name("providedidentry.name").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
- .property("blurb", ElementType.FIELD)
- .field().name("providedidentry.blurb").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
- .property("age", ElementType.FIELD)
- .field().name("providedidentry.age").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
- .entity(ProductCatalog.class).indexed()
- .similarity( DefaultSimilarity.class )
- .boost( 2 )
- .property( "id", ElementType.FIELD ).documentId().name( "id" )
- .property("name", ElementType.FIELD)
- .field().name("productCatalogName").index(Index.TOKENIZED).analyzer("en").store(Store.YES)
- .property("items", ElementType.FIELD)
- .indexEmbedded()
- .entity(Item.class)
- .property("description", ElementType.FIELD)
- .field().name("description").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
- .property("productCatalog", ElementType.FIELD)
- .containedIn()
- .entity(Departments.class)
- .classBridge(CatDeptsFieldsClassBridge.class)
- .name("branchnetwork")
- .index(Index.TOKENIZED)
- .store(Store.YES)
- .param("sepChar", " ")
- .classBridge(EquipmentType.class)
- .name("equiptype")
- .index(Index.TOKENIZED)
- .store(Store.YES)
- .param("C", "Cisco")
- .param("D", "D-Link")
- .param("K", "Kingston")
- .param("3", "3Com")
- .indexed()
- .property("deptsId", ElementType.FIELD)
- .documentId().name("id")
- .property("branchHead", ElementType.FIELD)
- .field().store(Store.YES)
- .property("network", ElementType.FIELD)
- .field().store(Store.YES)
- .property("branch", ElementType.FIELD)
- .field().store(Store.YES)
- .property("maxEmployees", ElementType.FIELD)
- .field().index(Index.UN_TOKENIZED).store(Store.YES)
- .entity( BlogEntry.class ).indexed()
- .property( "title", ElementType.METHOD )
- .field()
- .property( "description", ElementType.METHOD )
- .field()
- .property( "language", ElementType.METHOD )
- .analyzerDiscriminator(BlogEntry.BlogLangDiscriminator.class)
- .property("dateCreated", ElementType.METHOD)
- .field()
- .name("blog-entry-created")
- .analyzer("en")
- .store(Store.YES)
- .dateBridge(Resolution.DAY);
- cfg.getProperties().put( "hibernate.search.mapping_model", mapping );
}
public void NotUseddefineMapping() {
Added: search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java
===================================================================
--- search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java (rev 0)
+++ search/trunk/src/test/java/org/hibernate/search/test/configuration/ProgrammaticSearchMappingFactory.java 2009-12-08 11:19:42 UTC (rev 18157)
@@ -0,0 +1,123 @@
+package org.hibernate.search.test.configuration;
+
+import java.lang.annotation.ElementType;
+
+import org.apache.lucene.search.DefaultSimilarity;
+import org.apache.solr.analysis.EnglishPorterFilterFactory;
+import org.apache.solr.analysis.GermanStemFilterFactory;
+import org.apache.solr.analysis.LowerCaseFilterFactory;
+import org.apache.solr.analysis.NGramFilterFactory;
+import org.apache.solr.analysis.StandardTokenizerFactory;
+import org.hibernate.search.annotations.Factory;
+import org.hibernate.search.annotations.FilterCacheModeType;
+import org.hibernate.search.annotations.Index;
+import org.hibernate.search.annotations.Resolution;
+import org.hibernate.search.annotations.Store;
+import org.hibernate.search.bridge.builtin.LongBridge;
+import org.hibernate.search.cfg.ConcatStringBridge;
+import org.hibernate.search.cfg.SearchMapping;
+
+public class ProgrammaticSearchMappingFactory {
+
+ @Factory
+ public SearchMapping build() {
+ SearchMapping mapping = new SearchMapping();
+
+ mapping.fullTextFilterDef("security", SecurityFilterFactory.class).cache(FilterCacheModeType.INSTANCE_ONLY)
+ .analyzerDef( "ngram", StandardTokenizerFactory.class )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( NGramFilterFactory.class )
+ .param( "minGramSize", "3" )
+ .param( "maxGramSize", "3" )
+ .analyzerDef( "en", StandardTokenizerFactory.class )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( EnglishPorterFilterFactory.class )
+ .analyzerDef( "de", StandardTokenizerFactory.class )
+ .filter( LowerCaseFilterFactory.class )
+ .filter( GermanStemFilterFactory.class )
+ .entity( Address.class )
+ .indexed()
+ .similarity( DefaultSimilarity.class )
+ .boost( 2 )
+ .property( "addressId", ElementType.FIELD ).documentId().name( "id" )
+ .property("lastUpdated", ElementType.FIELD)
+ .field().name("last-updated")
+ .analyzer("en").store(Store.YES)
+ .calendarBridge(Resolution.DAY)
+ .property("dateCreated", ElementType.FIELD)
+ .field().name("date-created").index(Index.TOKENIZED)
+ .analyzer("en").store( Store.YES )
+ .dateBridge(Resolution.DAY)
+ .property("owner", ElementType.FIELD)
+ .field()
+ .property( "street1", ElementType.FIELD )
+ .field()
+ .field().name( "street1_ngram" ).analyzer( "ngram" )
+ .field()
+ .name( "street1_abridged" )
+ .bridge( ConcatStringBridge.class ).param( ConcatStringBridge.SIZE, "4" )
+ .property( "street2", ElementType.METHOD )
+ .field().name( "idx_street2" ).store( Store.YES ).boost( 2 )
+ .entity(ProvidedIdEntry.class).indexed()
+ .providedId().name("providedidentry").bridge(LongBridge.class)
+ .property("name", ElementType.FIELD)
+ .field().name("providedidentry.name").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+ .property("blurb", ElementType.FIELD)
+ .field().name("providedidentry.blurb").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+ .property("age", ElementType.FIELD)
+ .field().name("providedidentry.age").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+ .entity(ProductCatalog.class).indexed()
+ .similarity( DefaultSimilarity.class )
+ .boost( 2 )
+ .property( "id", ElementType.FIELD ).documentId().name( "id" )
+ .property("name", ElementType.FIELD)
+ .field().name("productCatalogName").index(Index.TOKENIZED).analyzer("en").store(Store.YES)
+ .property("items", ElementType.FIELD)
+ .indexEmbedded()
+ .entity(Item.class)
+ .property("description", ElementType.FIELD)
+ .field().name("description").analyzer("en").index(Index.TOKENIZED).store(Store.YES)
+ .property("productCatalog", ElementType.FIELD)
+ .containedIn()
+ .entity(Departments.class)
+ .classBridge(CatDeptsFieldsClassBridge.class)
+ .name("branchnetwork")
+ .index(Index.TOKENIZED)
+ .store(Store.YES)
+ .param("sepChar", " ")
+ .classBridge(EquipmentType.class)
+ .name("equiptype")
+ .index(Index.TOKENIZED)
+ .store(Store.YES)
+ .param("C", "Cisco")
+ .param("D", "D-Link")
+ .param("K", "Kingston")
+ .param("3", "3Com")
+ .indexed()
+ .property("deptsId", ElementType.FIELD)
+ .documentId().name("id")
+ .property("branchHead", ElementType.FIELD)
+ .field().store(Store.YES)
+ .property("network", ElementType.FIELD)
+ .field().store(Store.YES)
+ .property("branch", ElementType.FIELD)
+ .field().store(Store.YES)
+ .property("maxEmployees", ElementType.FIELD)
+ .field().index(Index.UN_TOKENIZED).store(Store.YES)
+ .entity( BlogEntry.class ).indexed()
+ .property( "title", ElementType.METHOD )
+ .field()
+ .property( "description", ElementType.METHOD )
+ .field()
+ .property( "language", ElementType.METHOD )
+ .analyzerDiscriminator(BlogEntry.BlogLangDiscriminator.class)
+ .property("dateCreated", ElementType.METHOD)
+ .field()
+ .name("blog-entry-created")
+ .analyzer("en")
+ .store(Store.YES)
+ .dateBridge(Resolution.DAY);
+ return mapping;
+
+ }
+}
15 years