[Hibernate-JIRA] Created: (HHH-3406) IndexOutOfBoundsException when a flush occurs during validation inside a flush
by vincent Larchet (JIRA)
IndexOutOfBoundsException when a flush occurs during validation inside a flush
------------------------------------------------------------------------------
Key: HHH-3406
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3406
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.6
Environment: 3.2.6ga, oracle11g, tomcat 6.0.16, spring 2.5.1, redhat5.2 or windows XP or debian etch
Reporter: vincent Larchet
Say we have entity A:
@Entity
public class A {
[...]
@AssertTrue
public boolean validateSomeCondition(){
//call service S
B=S.loadEntityB()
[.... do some stuff with B...]
}
}
In my hibernate session I modifiy several entities among them A1, A2, A3 (instances of A), then I flush the session that firsts validates A1. Inside A1.validateSomeCondition() I have to call a service that loads some data inside its own transaction, thus when it returns a commit is triggered that is intercepted an hibernate flushes its session, and not only entities bound to this transaction but the WHOLE session (including A2, A3 !!!). Then validation of A1 finishes successfully and A1 is saved to db, but right after that this exception occurs
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:596)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:319)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
[...]
I do not really know if flushing A2,A3 entites inside the 2nd flush is an issue or not (I do not mind actually...), so I suggest this quick fix:
inside ActionQueue method
private void executeActions(List list)
throws HibernateException
{
int size = list.size();
for(int i = 0; i < size; i++)
execute((Executable)list.get(i));
list.clear();
session.getBatcher().executeBatch();
}
replace the "static" int size = list.size(); for(int i = 0; i < size; i++) by an iterator...
thx
vincent
NB: we use OpenSessionInViewFilter
--
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
14 years, 9 months
[Hibernate-JIRA] Created: (ANN-823) Unit tests fail because Insert into ... values(upper(?)) fails on DB2
by Gail Badner (JIRA)
Unit tests fail because Insert into ... values(upper(?)) fails on DB2
---------------------------------------------------------------------
Key: ANN-823
URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-823
Project: Hibernate Annotations
Issue Type: Bug
Reporter: Gail Badner
The following tests fail with DB2Dialect:
org.hibernate.test.annotations.join.JoinTest.testFetchModeOnSecondaryTable()
org.hibernate.test.annotations.join.JoinTest.testCustomSQL()
due to failure on:
insert into Cat2 (storyPart2, id) values (upper(?), ?)
The following tests fail:
org.hibernate.test.annotations.query.QueryAndSQLTest.testEntitySQLOverriding()
org.hibernate.test.annotations.query.QueryAndSQLTest.testCollectionSQLOverriding()
due to failure on:
INSERT INTO CHAOS(name, nick_name, chaos_size, id) VALUES(upper(?),?,?,?)
The tests pass if upper(?) is changed to upper(? || ''), but this may not work on all dialects.
--
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
14 years, 9 months
[Hibernate-JIRA] Created: (HHH-2679) One to Many Unidirectional Association using Join Tables and <list> causes duplicate key constraint violation when an entry is deleted from the list.
by Priyajeet Hora (JIRA)
One to Many Unidirectional Association using Join Tables and <list> causes duplicate key constraint violation when an entry is deleted from the list.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Key: HHH-2679
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2679
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.2
Environment: Java 1.5, Hibernate 3.2, MySQL 5. Might also effect NHibernate similarly.
Reporter: Priyajeet Hora
Priority: Critical
Consider this unidirectional one-to-many relation done using join tables.
Person --> Address (*).
The hibernate mapping is pretty much the same as
http://www.hibernate.org/hib_docs/v3/reference/en/html/associations.html#...
Though I am using <list> rather than a <set>
Following is the DDL (presented roughly) created by the hbm2ddl tool.
Table PersonAddress
Person_id varcahr not null
Address_id varchar not null unique
Person_list_index integer not null
primary key (Person_id, Person_list_index)
I create a person1 - person_id=1.
I create add1, add2, add3 - address_id=2,3,4 respectively.
then I add all 3 addresses to the list in person1.
persist it to database.
all good.
At this point in the database --
person_id---person_list_index---address_id
1--0--2
1--1--3
1--2--4
I get person1 back.
I remove add1.
save person1 back.
CONSTRIANT VIOLATION HERE DUE TO DUPLICATE KEY.
looking at what hibernate does ...
So after 1st save and before remove this is whats in the database -
person_id---person_list_index---address_id
1--0--2
1--1--3
1--2--4
basically shows the one to many there.
I want to remove the record no. 1--0--2. That is the 1st one.
So with the 1st row gone, hibernate needs to shift other records up so that the new list index is assingned.
expected output----
1--0--3
1--1--4
This is how hibernate proceeds
Step1: save info and delete on 1--2--4, to get rid of that last record.
Step2: update 1--0--2 to 1--0--3
BANG...CONSTRAINT VIOLATION DUE TO DUPLICATE KEY.
Why? because "3" in that address_id column is already there and that column is "unique" according to DDL.
Step3: update 1--0--3 to info saved from step1, that is to 1--1--4.
But cant persist this since step 2 fails.
Basically the algorithm of copy the value up when a delete is performed is not doing the copy correctly.
Way to get around this is to remove the "unique" constrint, but then that makes the relation a many to many.
-----------------------------------------------------------------------------
CREATE TABLE `PERSON`
(
`PRESON_ID` varchar(255) NOT NULL, PRIMARY KEY (PRESON_ID)
)
CREATE TABLE `ADDRESS`
(
`ADDRESS_ID` varchar(255) NOT NULL, PRIMARY KEY (ADDRESS_ID)
)
CREATE TABLE `PERSONADDRESS`
(
`PERSON_ID` varchar(255) NOT NULL
, `PERSON_IDX` integer NOT NULL
, `ADDRESS_ID` varchar(255) NOT NULL UNIQUE, PRIMARY KEY (PERSON_ID, PERSON_IDX)
)
ALTER TABLE `PERSONADDRESS`
ADD INDEX `PERSONADDRESS_FK_PERSON` (`PERSON_ID`),
ADD CONSTRAINT `PERSONADDRESS_FK_PERSON`
FOREIGN KEY (`PERSON_ID`)
REFERENCES PERSON(`PERSON_ID`)
ALTER TABLE `PERSONADDRESS`
ADD INDEX `PERSONADDRESS_FK_ADDRESS` (`ADDRESS_ID`),
ADD CONSTRAINT `PERSONADDRESS_FK_ADDRESS`
FOREIGN KEY (`ADDRESS_ID`)
REFERENCES ADDRESS(`ADDRESS_ID`)
Person.hbm.xml
-------------------------
<list name="AddressList" lazy="false" table="PersonAddress">
<key column="PERSON_ID" />
<index column="PERSON_IDX" />
<many-to-many column="ADDRESS_ID" unique="true" class="Address" />
</list>
Address.hbm.xml
--------------------------
No information about Person, since this is a unidirectional association.
Target doesnt know about the source.
Test psuedocode
-------------------------
//start transaction
Person person = new Person();
Address add1 = new Address();
Address add2 = new Address();
Address add3 = new Address();
person.add(add1);
person.add(add2);
person.add(add3);
// persist to database
person.save
// end transaction
// start transaction
// get back that person from database
person.remove(add1);
// persist to database
person.save <<<<<<<<<<<<<<< FAILS, duplicate key constraint violation
// end transaction
--
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
14 years, 9 months
[Hibernate-JIRA] Created: (HHH-2341) ObjectNotFoundException on session.get() on non-existent object
by Timo Thomas (JIRA)
ObjectNotFoundException on session.get() on non-existent object
---------------------------------------------------------------
Key: HHH-2341
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2341
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1
Environment: HSQLDB 1.8.0
Reporter: Timo Thomas
Hibernate version:
3.2.1 GA (same for hibernate-annotations)
Mapping documents:
Parent.java (omitting package and some import declarations)
import javax.persistence.*;
@Entity
public class Parent {
public Integer id;
public Set<Child> children = new HashSet<Child>();
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
public Set<Child> getChildren() {
return children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
}
Child.java (omitting package and some import declarations)
import javax.persistence.*;
@Entity
public class Child {
public Integer id;
public Parent parent;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(optional = false)
@JoinColumn(name = "parent_fk")
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
Code between sessionFactory.openSession() and session.close():
Transaction transaction = session.beginTransaction();
Parent parent = new Parent();
parent.setName("p1");
session.persist(parent);
assertNotNull(parent.getId());
Integer parentId = parent.getId();
Child child = new Child();
child.setName("c1");
child.setParent(parent);
parent.getChildren().add(child);
session.persist(parent);
assertNotNull(child.getId());
Integer childId = child.getId();
transaction.commit();
session.close();
///////////////////////////////////////////
session = sessionFactory.openSession();
transaction = session.beginTransaction();
parent = (Parent) session.load(Parent.class, parentId);
child = (Child) session.load(Child.class, childId);
// child = (Child) session.get(Child.class, childId);
session.delete(parent);
// session.flush(); // !! required if session&transaction is re-opened and child is obtained with load(), otherwise exception on next line - BUG ?
child = (Child) session.get(Child.class, childId);
Full stack trace of any exception that occurs:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [model.Child#1]
at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.returnNarrowedProxy(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:187)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
at test.CascadeAnnotationTest.testBug(CascadeAnnotationTest.java:48)
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 junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:228)
at junit.framework.TestSuite.run(TestSuite.java:223)
at org.junit.internal.runners.OldTestClassRunner.run(OldTestClassRunner.java:35)
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)
The generated SQL (show_sql=true):
Hibernate: insert into Parent (id, name) values (null, ?)
Hibernate: call identity()
Hibernate: insert into Child (id, name, parent_fk) values (null, ?, ?)
Hibernate: call identity()
Hibernate: select parent0_.id as id0_0_, parent0_.name as name0_0_ from Parent parent0_ where parent0_.id=?
Hibernate: select children0_.parent_fk as parent3_1_, children0_.id as id1_, children0_.id as id1_0_, children0_.name as name1_0_, children0_.parent_fk as parent3_1_0_ from Child children0_ where children0_.parent_fk=?
Why is this exception thrown under these circumstances? Am I using the API in an undocumented/disallowed way? If yes, where exactly?
The Hibernate API doc says, that Session.get() returns null if an object can't be found. No exception should be thrown.
However, Session.get() at the end of sample code does return null as expected, if either
a) Session.get() is used instead of load() some lines above (see commented line)
b) the transaction and the session is isn't closed or reopened, respectively
c) Session.flush() is called before the final call to Session.get()
I'd like to understand why Hibernate behaves like this, which I presume is erroneous. I'm a beginner in Hibernate, but I couldn't get any help in the forum.
Timo
--
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
14 years, 9 months