[Hibernate-JIRA] Created: (HHH-2128) data corruption using one-to-one mapping
by Patrick Moore (JIRA)
data corruption using one-to-one mapping
----------------------------------------
Key: HHH-2128
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2128
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.0.cr4
Environment: hsqldb 1.8.0
Reporter: Patrick Moore
Priority: Blocker
Attachments: hibernatetests.zip
Please notice that this situation arose from the most minimal definition. Using the 'defaults' is what caused this issue!
See attached zip for definitions and reproduction test case.
Steps:
1. define two classes (Primary, Secondary) that have a one-to-one relationship.
2. save a primary with no assigned secondary object.
3. save another primary with a secondary object.
4. retrieve the first primary and it will have the secondary object saved in step 3.
5. retrieve the second primary and it will have no secondary object.
Suggested solution:
require that 'one-to-one' enforce an implicit non-null requirement between primary and secondary.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months
[Hibernate-JIRA] Created: (HHH-2126) collection not getting filtered to requested subclasses
by Patrick Moore (JIRA)
collection not getting filtered to requested subclasses
-------------------------------------------------------
Key: HHH-2126
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2126
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.0.cr4
Reporter: Patrick Moore
=========================
The setup
=========================
I have a class that has two maps defined in it to access MessageEndPointImpl instances. MessageEndPointImpl and MessageSourcePointImpl are subclasses stored in the same table.
The first map accesses MessageEndPointImpls by their database ids:
<map name="messageEndPointsByEntityKey" inverse="true" access="field"
cascade="all-delete-orphan">
<key column="BROADCAST_PROVIDER" not-null="true"/>
<map-key type="long" column="ID" />
<one-to-many
class="com.transparentpolitics.core.messagehandling.MessageEndPointImpl"/>
</map>
The second map is to access MessageEndPointImpls by their lookup key which only some MessageEndPointImpls have:
<map name="messageEndPointsByLookupKey" inverse="true" access="field"
where="LOOKUPKEY IS NOT NULL">
<key column="BROADCAST_PROVIDER" not-null="true"/>
<map-key type="string" column="LOOKUPKEY" />
<one-to-many
class="com.transparentpolitics.core.messagehandling.MessageEndPointImpl"/>
</map>
=======================
The problem
=======================
Trying to access the MessageEndPointImpls using the second map results in this exception. It is trying to include in the returned collection, the MessageSourcePointImpls. This is clearly wrong because the map definition specifies a one-to-many mapping with MessageEndPointImpl
org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: com.transparentpolitics.core.messagehandling.MessageEndPointImpl (loaded object was of wrong class class com.transparentpolitics.core.messagehandling.MessageSourcePointImpl)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1234)
at org.hibernate.loader.Loader.getRow(Loader.java:1186)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:568)
at org.hibernate.loader.Loader.doQuery(Loader.java:689)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1918)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentMap.values(PersistentMap.java:196)
at com.transparentpolitics.core.BroadcastProvider.getMessageEndPointSet(BroadcastProvider.java:425)
at com.transparentpolitics.core.BroadcastProvider.getMessageEndPointsMonitoringTopics(BroadcastProvider.java:491)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:185)
at com.transparentpolitics.core.BroadcastProvider$$EnhancerByCGLIB$$f7a6748d.getMessageEndPointsMonitoringTopics(<generated>)
==============================
Workaround:
==============================
changing the map definition to explicitly filter on the discriminator-value for MessageEndPointImpl works.
<map name="messageEndPointsByLookupKey" inverse="true" access="field"
where="LOOKUPKEY IS NOT NULL AND POINT_TYPE='MEP'">
<key column="BROADCAST_PROVIDER" not-null="true"/>
<map-key type="string" column="LOOKUPKEY" />
<one-to-many
class="com.transparentpolitics.core.messagehandling.MessageEndPointImpl"/>
</map>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months
[Hibernate-JIRA] Commented: (HHH-440) Extend properties on dynamic-component in sublcass
by Davide Baroncelli (JIRA)
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-440?page=co... ]
Davide Baroncelli commented on HHH-440:
---------------------------------------
May I ask if polymorphic components have been eventually implemented (*properly* or not ;) )? As far as I can see Hibernate 3.x feature set does not mention them, and it's a pity: the forums seem to have had various persons asking this feature. I'm asking this because I'm currently implementing a usertype for having component polymorphism and it's a pain in the ass: it involves a lot of "mapping" work that makes one feel as if there wasn't an ORM framework at all! And the normal hibernate hooks on creation do not work, and a lot of other problems...
> Extend properties on dynamic-component in sublcass
> ---------------------------------------------------
>
> Key: HHH-440
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-440
> Project: Hibernate3
> Type: Patch
> Components: core
> Versions: 3.0.2
> Environment: hibernte 3.0.2, hsqldb
> Reporter: William F. DeMoss II
> Assignee: Steve Ebersole
> Attachments: patch.txt
>
> Original Estimate: 1 hour
> Remaining: 1 hour
>
> Allow subclasses to add properties to super classes dynamic-component mapping. The was pretty much already implemented except for correct resolution from alias to column names. The following patch contains the fix as well as a test case. This patch is for hibernate 3.0.2, but it also cleanly applys on HEAD. All test cases that were passing before the patch pass after the patch.
> patch.txt
> Index: src/org/hibernate/persister/entity/BasicEntityPersister.java
> ===================================================================
> RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/persister/entity/BasicEntityPersister.java,v
> retrieving revision 1.27
> diff -u -r1.27 BasicEntityPersister.java
> --- src/org/hibernate/persister/entity/BasicEntityPersister.java 26 Apr 2005 20:28:27 -0000 1.27
> +++ src/org/hibernate/persister/entity/BasicEntityPersister.java 4 May 2005 23:45:55 -0000
> @@ -1107,9 +1107,15 @@
> * which takes the entity name.
> */
> protected int getSubclassPropertyTableNumber(String propertyName) {
> - Type type = propertyMapping.toType(propertyName);
> + final String rootPropertyName = StringHelper.root(propertyName);
> + Type type = propertyMapping.toType(rootPropertyName);
> if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) return 0;
> - int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), propertyName); //TODO: optimize this better!
> + if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
> + String unrooted = StringHelper.unroot(propertyName);
> + int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
> + if ( idx != -1 ) return getSubclassColumnTableNumberClosure()[idx];
> + }
> + int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName); //TODO: optimize this better!
> return index==-1 ? 0 : getSubclassPropertyTableNumber(index);
> }
>
> Index: src/org/hibernate/persister/entity/BasicEntityPropertyMapping.java
> ===================================================================
> RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/persister/entity/BasicEntityPropertyMapping.java,v
> retrieving revision 1.1
> diff -u -r1.1 BasicEntityPropertyMapping.java
> --- src/org/hibernate/persister/entity/BasicEntityPropertyMapping.java 13 Feb 2005 11:50:09 -0000 1.1
> +++ src/org/hibernate/persister/entity/BasicEntityPropertyMapping.java 4 May 2005 23:45:55 -0000
> @@ -29,9 +29,8 @@
> }
>
> public String[] toColumns(final String alias, final String propertyName) throws QueryException {
> - final String rootPropertyName = StringHelper.root(propertyName);
> return super.toColumns(
> - persister.generateTableAlias( alias, persister.getSubclassPropertyTableNumber(rootPropertyName) ),
> + persister.generateTableAlias( alias, persister.getSubclassPropertyTableNumber(propertyName) ),
> propertyName
> );
> }
> Index: test/org/hibernate/test/component/A.java
> ===================================================================
> RCS file: test/org/hibernate/test/component/A.java
> diff -N test/org/hibernate/test/component/A.java
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ test/org/hibernate/test/component/A.java 1 Jan 1970 00:00:00 -0000
> @@ -0,0 +1,42 @@
> +package org.hibernate.test.component;
> +
> +import java.util.Map;
> +
> +public class A {
> +
> + public int id;
> + public Map dynComp;
> +
> + public A() {
> + this(-1);
> + }
> +
> + public A(int id) {
> + this.id = id;
> + }
> +
> + public Map getDynComp() {
> + return dynComp;
> + }
> +
> + public void setDynComp(Map dynComp) {
> + this.dynComp = dynComp;
> + }
> +
> + public int getId() {
> + return id;
> + }
> +
> + public void setId(int id) {
> + this.id = id;
> + }
> +
> + public boolean equals(Object obj) {
> + if ( !( obj instanceof A ) ) return false;
> + return id == ( (A) obj ).id;
> + }
> +
> + public int hashCode() {
> + return id == -1 ? super.hashCode() : id;
> + }
> +}
> Index: test/org/hibernate/test/component/ABC.hbm.xml
> ===================================================================
> RCS file: test/org/hibernate/test/component/ABC.hbm.xml
> diff -N test/org/hibernate/test/component/ABC.hbm.xml
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ test/org/hibernate/test/component/ABC.hbm.xml 1 Jan 1970 00:00:00 -0000
> @@ -0,0 +1,30 @@
> +<?xml version="1.0"?>
> +<!DOCTYPE hibernate-mapping PUBLIC
> + "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
> + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
> +
> +<hibernate-mapping package="org.hibernate.test.component">
> +
> + <class name="A">
> + <id name="id"/>
> + <dynamic-component name="dynComp">
> + <property name="a" type="string"/>
> + </dynamic-component>
> + </class>
> +
> + <joined-subclass name="B" extends="A">
> + <key column="A"/>
> + <dynamic-component name="dynComp">
> + <property name="b" type="string"/>
> + </dynamic-component>
> + </joined-subclass>
> +
> + <joined-subclass name="C" extends="B">
> + <key column="B"/>
> + <dynamic-component name="dynComp">
> + <property name="c" type="string"/>
> + </dynamic-component>
> + </joined-subclass>
> +
> +
> +</hibernate-mapping>
> Index: test/org/hibernate/test/component/B.java
> ===================================================================
> RCS file: test/org/hibernate/test/component/B.java
> diff -N test/org/hibernate/test/component/B.java
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ test/org/hibernate/test/component/B.java 1 Jan 1970 00:00:00 -0000
> @@ -0,0 +1,13 @@
> +package org.hibernate.test.component;
> +
> +
> +public class B extends A {
> +
> + public B() {
> + super(-1);
> + }
> +
> + public B(int id) {
> + super(id);
> + }
> +}
> Index: test/org/hibernate/test/component/C.java
> ===================================================================
> RCS file: test/org/hibernate/test/component/C.java
> diff -N test/org/hibernate/test/component/C.java
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ test/org/hibernate/test/component/C.java 1 Jan 1970 00:00:00 -0000
> @@ -0,0 +1,13 @@
> +package org.hibernate.test.component;
> +
> +
> +public class C extends B {
> +
> + public C() {
> + super(-1);
> + }
> +
> + public C(int id) {
> + super(id);
> + }
> +}
> Index: test/org/hibernate/test/component/DynamicComponentTest.java
> ===================================================================
> RCS file: test/org/hibernate/test/component/DynamicComponentTest.java
> diff -N test/org/hibernate/test/component/DynamicComponentTest.java
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ test/org/hibernate/test/component/DynamicComponentTest.java 1 Jan 1970 00:00:00 -0000
> @@ -0,0 +1,84 @@
> +package org.hibernate.test.component;
> +
> +import java.util.HashMap;
> +import java.util.List;
> +
> +import org.hibernate.classic.Session;
> +import org.hibernate.test.TestCase;
> +
> +public class DynamicComponentTest extends TestCase {
> +
> + public DynamicComponentTest(String x) {
> + super(x);
> + }
> +
> + public void testQuery() throws Exception {
> + Session session = openSession();
> +
> + A a = new A(1);
> + a.setDynComp(new HashMap());
> + a.getDynComp().put("a", "a-a");
> + session.save(a);
> +
> + B b = new B(2);
> + b.setDynComp(new HashMap());
> + b.getDynComp().put("a", "b-a");
> + b.getDynComp().put("b", "b-b");
> + session.save(b);
> +
> + C c = new C(3);
> + c.setDynComp(new HashMap());
> + c.getDynComp().put("a", "c-a");
> + c.getDynComp().put("b", "c-b");
> + c.getDynComp().put("c", "c-c");
> + session.save(c);
> +
> + session.flush();
> +
> + List list = session.createQuery("from A a where a.dynComp.a = ?")
> + .setParameter(0, "a-a")
> + .list();
> +
> + assertEquals(1, list.size());
> + assertTrue(a.equals(list.get(0)));
> +
> + list = session.createQuery("from B b where b.dynComp.b = ?")
> + .setParameter(0, "b-b")
> + .list();
> +
> + assertEquals(1, list.size());
> + assertTrue(b.equals(list.get(0)));
> +
> + list = session.createQuery("from B b where b.dynComp.a = ?")
> + .setParameter(0, "b-a")
> + .list();
> +
> + assertEquals(1, list.size());
> + assertTrue(b.equals(list.get(0)));
> +
> + list = session.createQuery("from C c where c.dynComp.c = ?")
> + .setParameter(0, "c-c")
> + .list();
> +
> + list = session.createQuery("from C c where c.dynComp.b = ?")
> + .setParameter(0, "c-b")
> + .list();
> +
> + list = session.createQuery("from C c where c.dynComp.a = ?")
> + .setParameter(0, "c-a")
> + .list();
> +
> + assertEquals(1, list.size());
> + assertTrue(c.equals(list.get(0)));
> +
> + session.delete(c);
> + session.delete(b);
> + session.delete(a);
> + session.close();
> + }
> +
> + protected String[] getMappings() {
> + return new String[] { "component/ABC.hbm.xml" };
> + }
> +
> +}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months
[Hibernate-JIRA] Created: (EJB-219) Add an EntityManagerFactory.getCurrentEntityManager() method.
by James Olsen (JIRA)
Add an EntityManagerFactory.getCurrentEntityManager() method.
-------------------------------------------------------------
Key: EJB-219
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-219
Project: Hibernate Entity Manager
Type: New Feature
Components: EntityManager
Environment: Hibernate 3.2. Any/All.
Reporter: James Olsen
BACKGROUND
I'd like to code against the JPA standard, however my current EJB container vendor (like many others) is only providing JPA support as part of their EJB3 rollout which is at a very early stage.
JPA doesn't need a full EJB3 environment. The only required apsect that appears to be missing in existing EJB containers is container management and injection of a correctly scoped EntityManager. I can deal with the injection problem by having a Singleton accessor for the EntityManagerFactory in much the same way as the well known HibernateUtil deals with the SessionFactory. All that is left then is providing something similar to the automatic JTA/CMT context scoping of Sessions for EntityManager instances.
SUGGESTION
I would propose that a new custom API be added to org.hibernate.ejb.EntityManagerFactoryImpl in the form of a method called getCurrentEntityManager(). Internally this would construct an EntityManagerImpl that was configured to do sessionFactory.getCurrentSession() rather than sessionFactory.openSession() (inside the getRawSession() method), thereby leveraging Hibernates pre-existing capability to return correctly scoped units of work in a JTA/CMT environment. Thats sounds easy, but maybe there's more to it!?
JUSTIFICATION
The advantage of having such an API is that we can write to the JPA API without waiting for full EJB3 support in the container. The little bit of application code to obtain the EntityManagerFactory, cast to the Hibernate impl and call this custom method can easily be removed in the future when EntityManager injection is available.
I've looked at using Spring and Pitchfork but as great as they are, they are heavy handed when you already have a container and my customer demands a container and also has an aversion to non GA code (implies I'm confident the Hibernate 3.2 products will be GA soon - which I am!).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months
[Hibernate-JIRA] Created: (HHH-2123) clarification on the way interceptors and event system interact.
by Patrick Moore (JIRA)
clarification on the way interceptors and event system interact.
----------------------------------------------------------------
Key: HHH-2123
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2123
Project: Hibernate3
Type: Patch
Components: documentation
Versions: 3.2.0.cr4
Reporter: Patrick Moore
Please add this (or equivalent) to the bottom of section 12.1. (Interceptors):
===========================================
Interceptors are invoked by Hibernate's default event listeners. For example, interceptors' onSave() method is invoked by Hibernate's DefaultSaveOrUpdateEventListener
===========================================
Please add this (or equivalent) to the bottom of section 12.2 (Event System):
===========================================
When changing the event listeners be sure to keep the various Hibernate default listeners. These listeners actually perform much of Hibernate's persistence work, including invocation of the interceptors. Without those default listeners, Hibernate will quietly do nothing.
===========================================
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months
[Hibernate-JIRA] Commented: (HHH-1813) 2nd level cached collections are locked causing a cache miss
by Assaf Berg (JIRA)
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1813?page=c... ]
Assaf Berg commented on HHH-1813:
---------------------------------
I've investigated this using my test case going through DefaultInitializeCollectionEventListener, but it looks like Lock.isGettable is called and not Item.isGettable, and since that always returns false, null is returned and "Cached item was locked" message is logged.
> 2nd level cached collections are locked causing a cache miss
> ------------------------------------------------------------
>
> Key: HHH-1813
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1813
> Project: Hibernate3
> Type: Bug
> Versions: 3.1
> Environment: Hibernate 3.1, Oracle 10g, Linux
> Reporter: Assaf Berg
> Priority: Critical
> Attachments: testcase.tar.gz
>
>
> Using the second level cache, collections are fetched from the database due to the cached item being locked.
> This happens in the most simple use case:
> 1. Insert an entity with a collection
> 2. Commit.
> 3. Fetch the entity
> I've written a simple test case and see the following in the log file:
> 11:52:47,159 DEBUG [ReadWriteCache] Invalidating: domain.Cat.kittens#539957
> 11:52:47,177 DEBUG [ReadWriteCache] Inserting: domain.Cat#539957
> 11:52:47,179 DEBUG [ReadWriteCache] Inserted: domain.Cat#539957
> 11:52:47,180 DEBUG [ReadWriteCache] Inserting: domain.Kitten#540214
> 11:52:47,180 DEBUG [ReadWriteCache] Inserted: domain.Kitten#540214
> 11:52:47,181 DEBUG [ReadWriteCache] Releasing: domain.Cat.kittens#539957
> 11:52:49,221 DEBUG [ReadWriteCache] Caching: domain.Cat#539957
> 11:52:49,221 DEBUG [ReadWriteCache] Item was already cached: domain.Cat#539957
> 11:52:49,223 DEBUG [ReadWriteCache] Cache lookup: domain.Cat.kittens#539957
> 11:52:49,223 DEBUG [ReadWriteCache] Cached item was locked: domain.Cat.kittens#539957
> 11:52:49,229 DEBUG [ReadWriteCache] Caching: domain.Kitten#540214
> 11:52:49,229 DEBUG [ReadWriteCache] Item was already cached: domain.Kitten#540214
> 11:52:49,230 DEBUG [ReadWriteCache] Caching: domain.Cat.kittens#539957
> 11:52:49,231 DEBUG [ReadWriteCache] Cached: domain.Cat.kittens#539957
> domain.Cat.kittens [C/H/M/P]: 1/0/1/1
> domain.Cat [C/H/M/P]: 1/0/0/1
> domain.Kitten [C/H/M/P]: 1/0/0/1
> This happens whether the collection is mapped as inverse or not.
> I've attached the test case source and hbms (although it might need to be tweaked for the proper DB before running, and I didn't include the dependencies JARs).
> Here's a code excerpt of the interesting part (tx is TransactionTemplate using HibnerateTransactionManager and hibernate is HibernateTemplate from the spring framework):
> tx.execute(new TransactionCallback() {
> public Object doInTransaction(TransactionStatus status) {
> // create a Cat with one Kitten
> Cat cat = new Cat();
> Kitten kitten = new Kitten();
> cat.addKitten(kitten);
>
> hibernate.save(cat);
>
> return null;
> }
> });
>
> Thread.sleep(2000L);
>
> tx.execute(new TransactionCallback() {
> public Object doInTransaction(TransactionStatus status) {
> // load all cats
> List<Cat> allCats = hibernate.loadAll(Cat.class);
> return null;
> }
> });
> I can supply further information if needed.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
18 years, 2 months