Ole Hornischer
unread,Jan 9, 2011, 2:09:34 PM1/9/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Ebean ORM
HI everyone!
I recently started using Ebean for my Swing desktop app and am very
happy with it. However I ran into a little problem with updating one
of my beans.
I want to save/update the existing bean (it has an ID and it exists in
the database, i compared right before the save command). However when
saving I receive an OptimisticLockException (see below). When
debugging to the source of the exception i see it is being thrown
cause the row count is != 1 (I assume when loading the bean from the
DB prior to the update). However the bean is apparently loaded by a
query that includes all nun-null elements (of the bean to be saved)
which of course will not return anything, because the changed values
are not yet in the database. What am I doing wrong?
javax.persistence.OptimisticLockException: Data has changed. updated
[0] rows
at
com.avaje.ebeaninternal.server.core.PersistRequestBean.checkRowCount(PersistRequestBean.java:
509)
at
com.avaje.ebeaninternal.server.persist.dml.UpdateHandler.execute(UpdateHandler.java:
104)
at
com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:
105)
at
com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.update(DmlBeanPersister.java:
85)
at
com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeUpdateBean(DefaultPersistExecute.java:
110)
at
com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:
449)
If you need more information or code samples, please tell me which.
The bean and the saving method are attached below.
I hope I just oversaw something stupid and this can be fixed easily.
Personally I would expect that the query to retrieve the existing copy
of the bean from the DB would use the ID only, but maybe that has
other implications.
Thanks for your help,
Cheers Ole
Bean:
@Data
@Entity
public class Substitution {
@Id
private long id;
private Date date;
@ManyToOne
private StudyUnit studyUnit;
@ManyToOne
private Room altRoom;
@ManyToOne
private Teacher substitute;
@ManyToOne(cascade=CascadeType.ALL)
private Substitution insteadOf;
@ManyToOne
private SubstitutionPlanComment substitutionPlanComment;
private boolean locked = false;
private boolean moved = false;
@Version
private long version;
private String comment;
@Transient
private boolean conflicted = false;
@Transient
private Substitution isFor;
/**
* The plain constructor
*
*/
public Substitution() {
}
/**
* @param date
* @param studyUnit
*/
public Substitution(Date date,
StudyUnit studyUnit) {
super();
this.date = date;
this.studyUnit = studyUnit;
}
public void setInsteadOf(Substitution instead) {
insteadOf = instead;
if (insteadOf != null
&& !insteadOf.equals(instead)) {
DataRepository.instance().delete(insteadOf);
}
if (instead != null) {
instead.setIsFor(this);
}
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof Substitution)) return false;
return getId() == ((Substitution)o).getId();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[").append(getId()).append(" / ").append(getDate())
.append(" / ").append(getStudyUnit()).append(" / ")
.append(getSubstitute());
return sb.toString();
}
}
update method (the transaction handling is done by the calling methods
so that should be no issue, if I understand it correctly):
private static List<SubstitutionEvent> updateInternal(Substitution
sub, boolean silent) {
List<SubstitutionEvent> events = new
ArrayList<SubstitutionEvent>();
Substitution s = Ebean.find(Substitution.class, sub.getId());
if (s != null) {
if (s.getInsteadOf() != null
&& sub.getInsteadOf() == null) {
events.add(deleteInternal(s.getInsteadOf(), silent));
} else if (s.getInsteadOf() == null
&& sub.getInsteadOf() != null
&& !silent) {
events.add(new SubstitutionEvent(Type.CREATED,
sub.getInsteadOf()));
} else if (s.getInsteadOf() != null
&& sub.getInsteadOf() != null
&& !s.getInsteadOf().equals(sub.getInsteadOf())) {
events.add(deleteInternal(s.getInsteadOf(), silent));
if (!silent) {
events.add(new SubstitutionEvent(Type.CREATED,
sub.getInsteadOf()));
}
}
Ebean.save(sub); // Here is where the exception is initially
triggered. I already tried to use Ebean.update() but with the same
result
if (!silent) {
events.add(new SubstitutionEvent(Type.MODIFIED, sub));
}
} else {
events.add(saveInternal(sub, silent));
}
return events;
}