Reputation: 1964
I am trying to remove a record from database, but before removing it I am copying one of its children into another record, which runs into following error.
SEVERE: org.hibernate.StaleStateException: Batch update returned unexpected row count
from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:59)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3224)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3126)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3456)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:364)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:356)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:278)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:328)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
.....
1) In first function (get the list from record 18 and add to a new record)
....
User user = (User) session.get(User.class, 18L);
tx.commit();
User client = new User();
client.getmyList().setItems(user.getmyList().getItems());
return client;
2) In second function (remove record 18)
User user = (User) session.get(User.class, 18L);
session.delete(user);
3) In third function (save the new record)
session.save(client);
User class
@Entity
@DynamicUpdate
public class User{
.....
@OneToOne(cascade = CascadeType.ALL)
public UnitWatchList getmyList() {
return myList;
}
...
}
Upvotes: 0
Views: 151
Reputation: 3763
Hibernate has a default first level caching which associates with session object. So, once an access to a object will be cached and further accesses will be fetched from cache.
Second, assigning a reference object to other variable will only change references.
Lets trace your code
User user = (User) session.get(User.class, 18L)
client.getmyList().setItems(user.getmyList().getItems());
User user = (User) session.get(User.class, 18L);
session.delete(user);
session.save(client);
However, there is no actual object. Which is deleted.Prototype pattern is generally used for coping objects. clone method can also be overrided. However, once a copy of entity object created. New object will not be maintained by hibernate session which is another problem.
In my humble idea, removing an object if it will be saved again is not a good practice. Why do you remove if you want to save? Mappings should also be rearranged to solve these issues.
See also
Upvotes: 1
Reputation: 2819
I would probably just write a DAO method deleteAndMoveChildrensTo(Long victimId, Long recipientId), like this:
DAO Class:
public boolean deleteAndMoveChildrensTo(Long victimId, Long recipientId) {
User victim = (User) getSession().load(User.class, victimId);
User recipient = (User) getSession().load(User.class, recipientId);
for (UnitWatchList unitWatch : victim.getmyList().getItems()) {
unitWatch.setUser(recipient);
}
recipient.getmyList().addAll(victim.getmyList().getItems());
getSession().saveOrUpdate(recipient);
getSession().flush();
getSession().evict(victim);
victim = (User) getSession().load(User.class, victimId);
getSession().delete(victim);
return true;
}
and corresponding Service class as follows
Service Class.
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public boolean deleteAndMoveChildrensTo(Long victimId, Long recipientId) {
DAO.deleteAndMoveChildrensTo(victimId, recipientId);
}
try this out hope this will solve your problem...
Upvotes: 1
Reputation: 1777
Do you close the transaction in the second function, after session.delete(user);
? Maybe your problem is in session.delete()
and not in session.save()
.
How is mapped items
in UnitWatchList
?
Regards,
Upvotes: 1