[Hibernate-JIRA] Created: (HHH-4468) Exception when using hibernate as JPA provider: "Found two representations of same collection"
by Håvard Nesvold (JIRA)
Exception when using hibernate as JPA provider: "Found two representations of same collection"
----------------------------------------------------------------------------------------------
Key: HHH-4468
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4468
Project: Hibernate Core
Issue Type: Bug
Components: entity-manager
Affects Versions: 3.3.2
Environment: 3.3.2.GA
Reporter: Håvard Nesvold
I have a J2SE application where I use JPA with Hibernate as persistence provider. The versions of the required hibernate jars that I use are:
hibernate3.jar (3.3.2.GA)
hibernate-annotations.jar (3.4.0.GA)
hibernate-commons-annotations.jar (3.1.0.GA)
hibernate-entitymanager.jar (3.4.0.GA)
I have an entity where i have a bidirectional One-To-Many mapping. This is initialized to an empty list, something that clearly is allowed according to the JPA 1.0 spec.
i.e. I have:
in class Parent:
@OneToMany(mappedBy="parent", cascade = CascadeType.ALL)
private List<Child> children = ArrayList<Child>();
class Child:
@ManyToOne
@JoinColumn(name="PARENT_ID")
private Parent parent;
A certain sequence of actions result in a HibernateException being thrown (wrapped by JPA in a RollbackException):
* Obtain a new EntityManager
* Begin a transaction
* Fetch a Parent entity from the entity manager (this exists in the db), call this e.
* Apply an EntityManager.remove() on e
* Commit the transaction
* Begin a transaction
* Apply an EntityManager.persist() on e
* Commit the transaction
The exception is thrown on the last commit():
Code:
Caused by: org.hibernate.HibernateException: Found two representations of same collection: Parent.children
at org.hibernate.engine.Collections.processReachableCollection(Collections.java:176)
at org.hibernate.event.def.FlushVisitor.processCollection(FlushVisitor.java:60)
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:124)
...
I have tried to flush(), clear(), and pretty much everything on the entity manager (event fetching the Hibernate Sesssion and clearing this) - the only thing that helps is creating a new one before attempting the last transaction.
Moreover, after some investigation, the persisted entity actually seems to be persisted correctly - despite the exception (this also seems to hold true for any cascaded persists), perhaps the only erroneous thing here is the fact that an exception is thrown when it really should not?
--
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
12 years, 3 months
[Hibernate-JIRA] Created: (ANN-808) @Enumerated(ORDINAL) does not work on VARCHAR columns
by Eduardo Costa (JIRA)
@Enumerated(ORDINAL) does not work on VARCHAR columns
-----------------------------------------------------
Key: ANN-808
URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-808
Project: Hibernate Annotations
Issue Type: Bug
Affects Versions: 3.3.1.GA
Environment: Tested on Postgres, but the problem should be reproductible on any DB vendor
Reporter: Eduardo Costa
Copied from http://forum.hibernate.org/viewtopic.php?t=995698:
==========
Suppose I have this enum:
public enum Status { OK, NOK, NOT_APPLICABLE }
And this property:
@Column(name = "status")
@Enumerated(EnumType.ORDINAL)
private Status status;
And this table (legacy, CANNOT be changed):
CREATE TABLE tb_xxx (
id bigint NOT NULL,
status character varying(1) NOT NULL,
)
It leads to this exception:
java.lang.IllegalArgumentException: No enum const class mypkg.Status.1
java.lang.Enum.valueOf(Enum.java:196)
org.hibernate.type.EnumType.nullSafeGet(EnumType.java:110)
Taking a look at EnumType.java, it is clear that Hibernate imposes ordinal stored as number and name stored as varchar.
=========
IMHO, this is a "specification gap": JPA does not consider what to do if I'm trying to map a legacy enumerated value. Since I'm defining @Enumerated as "ordinal" and I have "0", "1", "2" on my database, I believe Hibernate should consider what I'm defining, not what an ancient DBA defined. Otherwise, I can't map this using only Hibernate Annotations/JPA (BTW, this code works with TopLink, only changing JPA provider on persistence.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
12 years, 3 months
[Hibernate-JIRA] Created: (HHH-3809) Improve Memory Management when Post Commit Listeners are enabled
by Shawn Clowater (JIRA)
Improve Memory Management when Post Commit Listeners are enabled
----------------------------------------------------------------
Key: HHH-3809
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3809
Project: Hibernate Core
Issue Type: Improvement
Components: core
Affects Versions: 3.3.1
Environment: N/A
Reporter: Shawn Clowater
This is somewhat related to the QueryCache behavior reported under http://opensource.atlassian.com/projects/hibernate/browse/HHH-3028
In this particular case however, it is the fact that when the session factory is configured to have post commit listeners it prevents the garbage collection of any entity that is modified during the session due to the fact that it is referenced in the executions list in the ActionQueue class. This makes any type of memory management by flushing/clearing the session ineffective if you're in the middle of a large batch that is inserting or updating a large amount of data.
i.e in our case we have 4 entities out of possibly 300 or so that we want to notify external systems if they change. However, by simply having the listeners defined they essentially block the remaining entities in the executions.
A potential workaround I guess might be to keep 2 session factories around with a different set of listeners but that seems a bit dirty.
There are 2.5 potential ways that I can think of that might address this.
1 - Have some sort of flag on the session to disable the post commit listeners. The onus would be on the user of the session to disable the listeners in the case where they know they aren't modifying anything that will need post commit handling.
2 - Add the ability to configure the post commit listeners by entity
a)With polymorphism - i.e. you could add a listener based on Object.class and it would apply to all entities and would behave much like it does now. You could also configure to Animal.class and would include Cat and Dog.
b)Without polymorphism - you could add a listener based on a specific entity class and it would only apply to that particular one. You would have an option to specify a null entity and it would default to what is there today.
In my miind, 2a is probably the best albeit slightly more complex to implement but I think would be a good value add.
I don't mind submitting a patch assuming that I'm not so far in left field that I should be committed.
--
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
12 years, 4 months
[Hibernate-JIRA] Created: (ANN-630) @ManyToMany and @Index
by Peter K. Guldbæk (JIRA)
@ManyToMany and @Index
----------------------
Key: ANN-630
URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-630
Project: Hibernate Annotations
Issue Type: Bug
Affects Versions: 3.3.0.ga
Environment: Windows Vista
java version "1.5.0_11"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)
Java HotSpot(TM) Client VM (build 1.5.0_11-b03, mixed mode)
Reporter: Peter K. Guldbæk
I have trouble adding an index to a column of a table which is part of a many-to-many property mapping. The following example causes a NullPointerException when generating the DDL (the exception can be seen at the end of my post):
@Entity @Table(name="usr")
public class User implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Integer id;
@ManyToMany(targetEntity=Target.class, cascade={})
@Index(name="fkey_usr_target", columnNames="usr_id")
@JoinTable(name="usr_target",
joinColumns=@JoinColumn(name="usr_id"),
inverseJoinColumns=@JoinColumn(name="target_id"))
public Collection<Target> targets;
}
@Entity @Table(name="target")
public class Target implements Serializable
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Integer id;
@Basic
public String myValue;
}
NullPointerException thrown when an @Index annotation is used with a @ManyToMany:
java.lang.NullPointerException
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1594)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:733)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:498)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1115)
at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:56)
at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:299)
at org.hibernate.tool.ant.Hbm2DDLExporterTask.execute(Hbm2DDLExporterTask.java:45)
at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:183)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
at sun.reflect.GeneratedMethodAccessor19.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:105)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:357)
at org.apache.tools.ant.Target.performTasks(Target.java:385)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1329)
at org.apache.tools.ant.Project.executeTarget(Project.java:1298)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1181)
at org.apache.tools.ant.Main.runBuild(Main.java:698)
at org.apache.tools.ant.Main.startAnt(Main.java:199)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
--
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
12 years, 4 months
[Hibernate-JIRA] Created: (HHH-2318) Sometimes wrong classloader used for proxy interfaces
by Jan Wiemer (JIRA)
Sometimes wrong classloader used for proxy interfaces
-----------------------------------------------------
Key: HHH-2318
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2318
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1
Reporter: Jan Wiemer
For some of our business classes we used a Mapping declaring the class to be lazy initialized and providing a proxy interface like e.g.:
<class name="TestClassImpl" proxy="TestClass" table="testTable" lazy="true"> ... </class>
Using classes mapped this way - e.g. as endpoint of a one to one relation - sporadically leads to exceptions like the following:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of test.AbstractTestClass2Impl.testField
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:104)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:337)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:200)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3514)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:129)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2211)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:388)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:804)
Note that the application is residing in a different classloader than hibernate (and CGLIB...).
Examining the situation we see that the value passed to the setter was a CGLIB proxy. Internally the proxy stores an array of interfaces the proxy should implement. In our situation this interface contains the HibernateProxy interface and our business interface provided as proxy interface in the mapping. In this interface array we checked the classloader of the interfaces. As expected the HibernateProxy interface is loaded by the system classloader and our interface was loaded by our custom classloader. However examining the actual interfaces of the proxy (with proxy.getClass().getInterfaces()[i].getClassLoader() for all i) shows that all interfaces are loaded with the system classloader. This causes the exception above.
Doing some more experiments we experience that the problem does not occur all the time. Sometimes the actual proxy interfaces are as expected (the HibernateProxy interface is loaded by the system classloader and our interface was loaded by our custom classloader). We notice that each time the test failed the HibernateProxy was the first interface in the interface array stored in the proxy.
Some experiments with the CGLIB (the Enhancer class) shows us that (if there is no superclass given) they use the classloader of the first passed interface as default classloader (compare method net.sf.cglib.proxy.Enhancer.getDefaultClassLoader()).
Finally we find out that hibernate passes the proxy interfaces in an arbitrary order since they are using a HashSet for the proxy interfaces in the method org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter). This Hash set is passed to the method org.hibernate.proxy.pojo.cglib.CGLIB_ProxyFactory.postInstantiate(...). There it is simply converted to an Array (leading to a randomized order).
As a workaround it is possible to patch the class org.hibernate.proxy.pojo.cglib.CGLIB_ProxyFactory and add reorganize the array if the HibernateProxy interface is the first one:
this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
//----->PATCH<--------
if(this.interfaces.length > 1) {
Class firstIfc = this.interfaces[0];
if(firstIfc.getName().startsWith("org.hibernate")) {
this.interfaces[0] = this.interfaces[1];
this.interfaces[1] = firstIfc;
System.err.println("Replace: " + firstIfc.getName() + " by " + this.interfaces[0].getName());
}
}
//--------------------
After applying this patch everything woks as expected.
Compare with the discussion in:
http://forum.hibernate.org/viewtopic.php?p=2334617#2334617
--
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
12 years, 4 months
[Hibernate-JIRA] Created: (HHH-3603) Hibernate custome classloader
by Behrang Javaherian (JIRA)
Hibernate custome classloader
-----------------------------
Key: HHH-3603
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3603
Project: Hibernate Core
Issue Type: New Feature
Affects Versions: 3.3.0.GA
Reporter: Behrang Javaherian
We are trying to use hibernate in a OSGi like kind of environment. We have a code module that creates the session factory. We want to be able to add classes to session factory and recreated the session factory as needed. But hibernate is always using the current class loader which cause class cast exception if we try to add model classes from child bundles (which has their own class loader). To overcome this issue we had to patch the hibernate internal ReflectHelper and change the classForNameMethod to this:
return PlugableClassFinder.getInstance().classForName(name);
and here is the code for PlugableClassFinder class:
public class PlugableClassFinder {
private Set<ClassLoader> classLoaders = new HashSet<ClassLoader>();
public Class classForName(String name) throws ClassNotFoundException {
try {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if ( contextClassLoader != null ) {
return contextClassLoader.loadClass(name);
}
}
catch ( Throwable t ) {
}
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
}
//now look into the registerred class loaders
for (ClassLoader classLoader : classLoaders) {
try {
return classLoader.loadClass(name);
} catch (ClassNotFoundException e) {
}
}
throw new ClassNotFoundException("Cannot find class: " + name);
}
public void registerClassLoader(ClassLoader classLoader) {
classLoaders.add(classLoader);
}
public void deregisterClassLoader(ClassLoader classLoader) {
classLoaders.remove(classLoader);
}
private static final PlugableClassFinder instance = new PlugableClassFinder();
public static PlugableClassFinder getInstance() {
return instance;
}
}
Now every bundle will register its class loader with PlugableClassFinder class.
Maybe hibernate should either allow plugging new class loaders to resolve classes or provide a hook o an interface that we can implement to replace the internal class resolving mechanism. For the moment our approach if working for us.
Regards
Behrang Javaherian
http://www.beyondng.com
--
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
12 years, 4 months