[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 …
[View More]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
[View Less]
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" …
[View More]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
[View Less]
12 years, 4 months
[Hibernate-JIRA] Created: (HHH-3441) Null pointer exception on org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
by DEROUET (JIRA)
Null pointer exception on org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
--------------------------------------------------------------------------------------------
Key: HHH-3441
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3441
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.5
Environment: Hibernate 3.25., Oracle 10g, Spring 2.5.5
…
[View More]Reporter: DEROUET
Priority: Blocker
The issue concerns a problem already signaled in different forums, and I decided to report it in JIRA, because many people have this same problem and after days and days of work around, the solutions possibles are heavy or dangerous for a database integrity (for example remove a non-nullability constraint...).
Here it is the problem a previous forum participant had perfectly summarized (see http://opensource.atlassian.com/projects/hibernate/browse/HHH-2326):
A null pointer exception is thrown when:
a) we have a composite key with one of the attributes of the key being an FK to another persistent class.
b) The other persistent class has an ID field whose value is being generated.
c) The instance of the other persistent class is transient (does not yet have an ID)
We do not get the null pointer if we explicitly set the ID (generator=assigned)
Here it is the failure trace:
-->
-->
java.lang.NullPointerException
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:120)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:279)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:189)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
at org.hibernate.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:240)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:189)
at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:512)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:80)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:747)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:744)
at eu.cec.argus.bcm.dao.businessContinuityEvent.BusinessContinuityEventDAOImpl.createBCEvent(BusinessContinuityEventDAOImpl.java:39)
at eu.cec.argus.bcm.dao.businessContinuityEvent.BusinessContinuityEventDAOTest.testSaveBcEventAndRelatedMessagesAndMeetings(BusinessContinuityEventDAOTest.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:198)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:274)
at org.springframework.test.context.junit4.SpringMethodRoadie$2.run(SpringMethodRoadie.java:207)
at org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:254)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:26)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:36)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Here they are my classes:
@Entity
@Table(name = "BCM_BC_EVENT")
@IdClass(BusinessContinuityEvent.BusinessContinuityEventId.class)
@SequenceGenerator(name = "Generator.BusinessContinuityEvent", sequenceName = "SEQ_BCM_BC_EVENT")
public class BusinessContinuityEvent implements Serializable {
@Embeddable
public static class BusinessContinuityEventId implements Serializable {
private static final long serialVersionUID = 3513299649110908676L;
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Generator.BusinessContinuityEvent")
@Column(name = "BCE_ID", insertable = false, updatable = false, nullable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumn(name = "EVE_ID", referencedColumnName = "EVE_ID", nullable = false)
private Event event;
public BusinessContinuityEventId(){
}
public BusinessContinuityEventId(Long id, Event event) {
this.id = id;
this.event = event;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BusinessContinuityEventId) {
BusinessContinuityEventId other = (BusinessContinuityEventId) obj;
return this.event.getId().equals(other.event.getId())
&& this.id.equals(other.id);
}
return false;
}
@Override
public int hashCode() {
return this.event.getId().hashCode() ^ this.id.hashCode();
}
}
private static final long serialVersionUID = 5385009048448590115L;
@Id
private Long id;
@Id
private Event event;
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumns({
@JoinColumn(name = "BCE_ID", referencedColumnName = "BCE_ID"),
@JoinColumn(name = "EVE_ID", referencedColumnName = "EVE_ID")})
private List<Message> messages;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
}
--
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
[View Less]
12 years, 5 months
[Hibernate-JIRA] Created: (HHH-2808) CLONE -Impossible to define caching for a subclass's collection in hibernate.cgf.xml
by Sebastien Blind (JIRA)
CLONE -Impossible to define caching for a subclass's collection in hibernate.cgf.xml
-------------------------------------------------------------------------------------
Key: HHH-2808
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2808
Project: Hibernate3
Issue Type: Bug
Components: caching (L2)
Affects Versions: 3.2.5
Environment: Hibernate 3.2.5
Sybase
Reporter: Sebastien Blind
…
[View More]Basically, hibernate allows to define <cache usage="transactional"/> inside the subclass mapping, i.e.
<subclass name="SubClass" extends="BaseClass" discriminator-value="xxx">
<bag name="subClassLinks" lazy="false" inverse="true" batch-size="100">
<cache usage="transactional" region="xxx"/>
<key column="xxx" not-null="true"/>
<one-to-many class="xxx"/>
</bag>
<join table="xxx">
</join>
</subclass>
but it's not allowed to do the same using <collection-cache collection="subClass.myCollection" region="xxx" usage="transactional"/>.
It throws:
Exception in thread "main" org.hibernate.MappingException: Cannot cache an unknown collection: subClass.myCollection
at org.hibernate.cfg.Configuration.setCollectionCacheConcurrencyStrategy(Configuration.java:1984)
at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1568)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1534)
at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1508)
at org.hibernate.cfg.Configuration.configure(Configuration.java:1428)
--
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
[View Less]
12 years, 5 months