[Hibernate-JIRA] Created: (HHH-7122) one-to-one with cascading delete of orphans causes IllegalArugmentException
by Michael Cameron (JIRA)
one-to-one with cascading delete of orphans causes IllegalArugmentException
---------------------------------------------------------------------------
Key: HHH-7122
URL: https://hibernate.onjira.com/browse/HHH-7122
Project: Hibernate ORM
Issue Type: Bug
Components: core
Affects Versions: 4.1.0, 3.6.10
Environment: Hibenate 3.6.x, 4.1.x (probably all since HHH-4726, but only tested on 3.6 and master branches)
Reporter: Michael Cameron
Priority: Critical
Attachments: hibernate-3.6-test-patch.diff, hibernate-master-test-patch.diff
Hibernate does not handle cascading deletes of orphans one-to-one properties.
For example in the following relationship:
{code:xml}
<class name="Employee">
<id name="id" type="long" column="id">
<generator class="increment" />
</id>
<one-to-one name="info"
property-ref="employee"
class="EmployeeInfo"
cascade="all,delete-orphan"
constrained="false" />
</class>
<class name="EmployeeInfo">
<id name="id" type="long" column="id">
<generator class="increment" />
</id>
<many-to-one name="employee"
column="employee_id"
unique="true"
not-null="true" />
</class>
{code}
If you retrieve an Employee with an EmployeeInfo from the DB, then set the employee.info to null, the first flush will correctly delete the orphan, but every flush after that in the same session will fail with an Illegal Argument Exception:
{{java.lang.IllegalArgumentException: object is not an instance of declaring class}}
I've researched the issue about as far as I can take it. The initial proximate case is that {{Cascade.cascadeProperty}} gets the entity name of the parent to pass on to the delete action. On the second call to flush, the value has been deleted, so it uses the entity name to look up the persister in {{DefaultDeleteEventListener.deleteEntity}}. It uses that persister to try to get the ID, but that's the persister of the parent class to get the ID of the child class, which fails with the exception above. I tried passing {{null}} in as the entityName so it would look up the persister using just the object, but that fails because then the delete has nothing to delete (it actually has been deleted already). That helped me understand the issue better.
In this case, the loadedState of the parent remains in place after the cascaded delete of the child because none of it's direct properties changes. So after the initial flush with the delete of the child, the next flush will still find the child object in the loaded state, but it is no longer in the session's persistence context, and it fails with the IllegalArgumentException above.
I don't know the hibernate internals above, so I don't know if the direct solution I'm thinking of would work: update the loaded state of the parent in {{Cascade.cascadeProperty}} after it calls {{eventSource.delete}}. Is this too direct? Does it need to happen with the action queue is actually executed? Is there enough information upon execution of this child to update the parent like EntityInsertAction and EntityUpdateAction?
I've attached patch files the 3.6 and master branch with tests that fail because of this issue. I wouldn't mind making changes to fix the problem and submitting a pull request, but I'll need guidance on how to approach it.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 11 months
[Hibernate-JIRA] Created: (HHH-6589) Support "Any" mappings when building metamodel
by Robert Brady (JIRA)
Support "Any" mappings when building metamodel
----------------------------------------------
Key: HHH-6589
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6589
Project: Hibernate Core
Issue Type: Improvement
Components: entity-manager
Affects Versions: 3.5.6
Environment: Hibernate entity manager 3.5.5, PostgreSQL 8.4
Reporter: Robert Brady
I am upgrading from Hibernate 3.2.x to 3.5.5 and getting UnsupportedOperationExceptions thrown when Hibernate is trying to create the metamodel. This is due to the dependency of my application upon jBPM 3.x, which uses "any" mappings for some of its classes.
The exception occurs in org.hibernate.ejb.metamodel.AttributeFactory.determineAttributeMetadata(...)
{noFormat}
java.lang.UnsupportedOperationException: any not supported yet
at org.hibernate.ejb.metamodel.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:452)
{noFormat}
It is due to the logic in AttributeFactory at line 451:
{noFormat}
if ( type.isAnyType() ) {
throw new UnsupportedOperationException( "any not supported yet" );
}
{noFormat}
The "Big Hammer" approach of globally disabling the creation of the metamodel with the property setting:
{noFormat}
hibernate.ejb.metamodel.generation=disabled
{noFormat}
is not feasible: other components in my application depend upon the criteria search api, which need a generated meatamodel. Splitting the single application persistence unit into two parts ( one for the jBPM persisted classes with metamodel disabled and all other classes with metamodel enabled) is not feasible either. The split persistence unit approach would also split transaction boundaries of operations that are desired to be in a single transaction.
Hibernate should support "any" mappings in the metamodel. The @Any annotation is supported in Hibernate Annotation 3.5.5.
If Hibernate can not support "any" mappings then maybe it could:
* Allow the exclusion of persistent classes by package in the metamodel. I tried this successfully by changing the following code in org.hibernate.ejb.EntityManagerFactoryImpl constructor:
{noFormat}
...
List<PersistentClass> persistentClasses = new ArrayList<PersistentClass>();
while (classes.hasNext()) {
PersistentClass persistentClass = classes.next();
// Hardcode jBPM classes for now, but make tidy with a property like "hibernate.ejb.metamodel.excluded.pkgs"
if (persistentClass.getClassName().startsWith("org.jbpm")) {
continue;
} else {
persistentClasses.add(persistentClass);
}
}
// a safe guard till we are confident that metamodel is wll tested
if (!"disabled".equalsIgnoreCase(cfg.getProperty("hibernate.ejb.metamodel.generation"))) {
this.metamodel = MetamodelImpl.buildMetamodel(persistentClasses.iterator(),
(SessionFactoryImplementor) sessionFactory);}
...
{noFormat}
* Exclude persistent classes having "any" mappings from the metamodel generation.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 11 months
[Hibernate-JIRA] Created: (JPA-24) java.sql.SQLException: Invalid argument in JDBC call: parameter index out of range when trying to persist an entity mapped with insertable = false, updatable = false on @Column
by Karsten Wutzke (JIRA)
java.sql.SQLException: Invalid argument in JDBC call: parameter index out of range when trying to persist an entity mapped with insertable = false, updatable = false on @Column
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: JPA-24
URL: http://opensource.atlassian.com/projects/hibernate/browse/JPA-24
Project: Java Persistence API
Issue Type: Bug
Environment: Hibernate 4.0.0.CR4, HSQLDB 2.0, MySQL 5.1
Reporter: Karsten Wutzke
The following mappings are all JPA 1.0 compatible (no derived identifiers):
{code:Company.java}
@Entity
@Table(name = "Companies")
public class Company
{
@Id
@Column
private Integer id;
@Column
private String name;
...
}
{code}
{code:PQ.java}
@Entity
@Table(name = "PQs")
public class PQ implements Serializable
{
@Id
@Column
private Integer id;
@Column
private String name;
...
}
{code}
{code:Partnership.java}
@Entity
@Table(name = "Partnerships")
@IdClass(value = PartnershipId.class)
public class Partnership implements Serializable
{
@Id
@Column(name = "pq_id", insertable = false, updatable = false)
private Integer pqId;
@Id
@Column(name = "company_id", insertable = false, updatable = false)
private Integer companyId;
@Column(name = "ordinal_nbr")
private Integer ordinalNbr;
@ManyToOne
@JoinColumn(name = "pq_id", referencedColumnName = "id")
private PQ pq;
@ManyToOne
@JoinColumn(name = "company_id", referencedColumnName = "id")
private Company company;
...
}
{code}
{code:PartnershipId.java}
public class PartnershipId implements Serializable
{
private Integer pqId;
private Integer companyId;
public PartnershipId()
{
}
public PartnershipId(Integer pqId, Integer companyId)
{
this.pqId = pqId;
this.companyId = companyId;
}
...
}
{code}
Note, the insertable = false, updatable = false on @JoinColumn relationships.
Running the following test code
{code:Main.java}
public class Main
{
private static String PERSISTENCE_UNIT_NAME = "standalonePu";
private static EntityManagerFactory emf;
private static EntityManager em;
private static EntityTransaction trans;
public static void main(String[] args)
{
setUp(PERSISTENCE_UNIT_NAME);
trans.begin();
PQ detachedPq = new PQ(1, "Test PQ");
Company detachedCompany = new Company(1, "Test Company");
PQ pq = em.merge(detachedPq);
Company company = em.merge(detachedCompany);
Partnership detachedPartnership = new Partnership(1, 1, 1);
detachedPartnership.setPQ(pq);
detachedPartnership.setCompany(company);
Partnership partnership = em.merge(detachedPartnership);
partnership = em.find(Partnership.class, new PartnershipId(1, 1));
System.out.println("Persistent partnership = ("
+ partnership.getPQId() + ", "
+ partnership.getCompanyId() + ", "
+ partnership.getOrdinalNbr() + ")");
trans.commit();
close();
}
private static void setUp(String puName)
{
emf = Persistence.createEntityManagerFactory(puName);
em = emf.createEntityManager();
trans = em.getTransaction();
}
private static void close()
{
em.close();
emf.close();
}
}
{code}
fails with a really strange exception:
ERROR: Invalid argument in JDBC call: parameter index out of range: 4
Exception in thread "main" javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:90)
at main.Main.main(Main.java:44)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1347)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1280)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:78)
... 1 more
Caused by: org.hibernate.exception.GenericJDBCException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hibernate.exception.internal.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:148)
at org.hibernate.exception.internal.SQLStateConverter.convert(SQLStateConverter.java:136)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:124)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:131)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:80)
at $Proxy12.setInt(Unknown Source)
at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$1.doBind(IntegerTypeDescriptor.java:57)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:82)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300)
at org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:358)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2599)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2836)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3276)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:344)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1084)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:319)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:100)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:173)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
... 1 more
Caused by: java.sql.SQLException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.outOfRangeArgument(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.checkSetParameterIndex(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.setInt(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:124)
... 22 more
Caused by: org.hsqldb.HsqlException: Invalid argument in JDBC call: parameter index out of range: 4
at org.hsqldb.error.Error.error(Unknown Source)
... 31 more
I've also tested this with MySQL with the same JDBC exception.
Note the workaround to resolve this is to put `..., insertable = false, updatable = false` onto the relationships' `@JoinColumn`s (but it's not really what I want).
Please fix.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 11 months
[Hibernate-JIRA] Created: (HHH-7048) Remove resolver classes
by John Verhaeg (JIRA)
Remove resolver classes
-----------------------
Key: HHH-7048
URL: https://hibernate.onjira.com/browse/HHH-7048
Project: Hibernate ORM
Issue Type: Task
Components: metamodel
Affects Versions: 4.1.0
Reporter: John Verhaeg
Assignee: John Verhaeg
Resolvers are currently called at the end of the MetadataImpl constructor as a temporary solution until a proper solution for creating bindings can be developed. However, it appears these can be removed after integrating their logic in an appropriate location within the Binder.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 11 months
[Hibernate-JIRA] Created: (HHH-6414) CPU spinning, stuck on getResultList()
by Anthony Ogier (JIRA)
CPU spinning, stuck on getResultList()
--------------------------------------
Key: HHH-6414
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6414
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.1
Environment: Hibernate Annotations 3.4.0.GA, Hibernate 3.3.1.GA, Hibernate Commons Annotations 3.1.0.GA, Hibernate EntityManager 3.4.0.GA, Seam 2.2.1.Final, JBoss 5.1.0.GA, Windows Server 2008 64bits, Microsoft SQL Server 10.00.4000, JDBC driver: Microsoft SQL Server 2005 JDBC Driver, version: 1.2.2828.100
Reporter: Anthony Ogier
I've got a web application which is well tested (JMeter etc), and suddenly today, 2 of JBoss threads were stuck on a getResultList(), using 100% of the CPU.
Here is the stack for each of the threads :
{noformat}
Thread: http-0.0.0.0-8080-2 : priority:5, demon:true, threadId:156, threadState:RUNNABLE
java.util.HashMap.put(HashMap.java:374)
org.hibernate.engine.StatefulPersistenceContext.addCollection(StatefulPersistenceContext.java:787)
org.hibernate.engine.StatefulPersistenceContext.addUninitializedCollection(StatefulPersistenceContext.java:756)
org.hibernate.type.CollectionType.getCollection(CollectionType.java:642)
org.hibernate.type.CollectionType.resolveKey(CollectionType.java:430)
org.hibernate.type.CollectionType.resolve(CollectionType.java:424)
org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
org.hibernate.loader.Loader.doQuery(Loader.java:752)
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
org.hibernate.loader.Loader.doList(Loader.java:2228)
org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
org.hibernate.loader.Loader.list(Loader.java:2120)
org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:361)
org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
org.hibernate.impl.SessionImpl.list(SessionImpl.java:1148)
org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:67)
{noformat}
I've seen some similar problems here [JGRP-525|https://issues.jboss.org/browse/JGRP-525] and here [JBMESSAGING-1676|https://issues.jboss.org/browse/JBMESSAGING-1676] and they are talking about concurrency ...
--
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, 11 months
[Hibernate-JIRA] Created: (HHH-6607) Exceptions being hidden in JDBCTransation
by Rich Christy (JIRA)
Exceptions being hidden in JDBCTransation
-----------------------------------------
Key: HHH-6607
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6607
Project: Hibernate Core
Issue Type: Bug
Components: envers
Affects Versions: 3.6.7
Environment: The issue happens when the audit schema is different from the primary schema say because of a column change. The database session is rolled back but the exception isn't thrown up to any levels past the notifyLocalSynchsBeforeTransactionCompletion() so any applications needing to recover from database failures cannot - say rolling back application caches.
The way to reproduce this is to drop a column in the aud table for any domain object and try to insert the data
Reporter: Rich Christy
2011-08-24 16:00:15,886 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2242)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2678)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at org.hibernate.envers.synchronization.AuditSync.beforeCompletion(AuditSync.java:161)
at org.hibernate.transaction.JDBCTransaction.notifyLocalSynchsBeforeTransactionCompletion(JDBCTransaction.java:274)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:140)
at org.openspaces.persistency.hibernate.DefaultHibernateExternalDataSource.executeBulk(DefaultHibernateExternalDataSource.java:107)
at com.skyroad.motion.transactionmanager.util.TransactionMirrorExternalDataSource.executeBulk(TransactionMirrorExternalDataSource.java:32)
What the code is doing in the exception handling of AuditSync.java (5th line from the bottom in the stack track) is rolling back the transaction as far as the hibernate session is concerned and then unconditionally throwing the exception to the next level. However, the code in notifyLocalSynchsBeforeTransactionCompletion() eating the exception so Gigaspaces isn't aware that it happened. This would explain why the database writes are rolled back but the space isn't.
public void beforeCompletion() {
if (workUnits.size() == 0 && undoQueue.size() == 0) {
return;
}
try {
// see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
Session temporarySession = null;
try {
temporarySession = session.getFactory().openTemporarySession();
executeInSession(temporarySession);
temporarySession.flush();
} finally {
if (temporarySession != null) {
temporarySession.close();
}
}
} else {
executeInSession(session);
// Explicity flushing the session, as the auto-flush may have already happened.
session.flush();
}
} catch (RuntimeException e) {
// Rolling back the transaction in case of any exceptions
//noinspection finally
try {
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
} finally {
//noinspection ThrowFromFinallyBlock
throw e;
}
}
}
private void notifyLocalSynchsBeforeTransactionCompletion() {
if (synchronizations!=null) {
for ( int i=0; i<synchronizations.size(); i++ ) {
Synchronization sync = (Synchronization) synchronizations.get(i);
try {
sync.beforeCompletion();
}
catch (Throwable t) {
log.error("exception calling user Synchronization", t);
}
}
}
}
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
12 years, 11 months