Home » Eclipse Projects » EclipseLink » @Version field does partially update?
@Version field does partially update? [message #387016] |
Tue, 07 April 2009 08:32 ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Hi,
I have a problem with the @Version annotated field. Working with a
Superclass 'AbstractEntity with the fields annotated with @Id and @Version
and two subclasses, say Parent and Child, where Parent has a @OneToMany to
Child, I try to update the parent object containing several already
persistent children using the merge method. In the database (mysql 5.0)
the version field is updated (oldValue + 1), but in the entities property
(int version, annotated with @Version), the value stays the same. A second
merge fails then, because the version field in the database is higher than
that in the entity.
Has anybody an idea what I am doing wrong?
Thank you in advance!
Christian
|
|
| |
Re: @Version field does partially update? [message #387039 is a reply to message #387023] |
Wed, 08 April 2009 20:02 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Hi James,
I mean, that I use the same object, but maybe I understand the mechanism
not perfectly. Anyway, I have this problem just with one class. All entity
classes inherit the property version from the superclass (annotated with
@MappedSuperclass). All other subclasses merge without any problems. Also
I use for the different classes the same routine. Can you give me a hint
where to look? In the eclipselink wiki I found nothing that could have
helped me.
Thank you!
|
|
|
Re: @Version field does partially update? [message #387070 is a reply to message #387039] |
Thu, 09 April 2009 13:39 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
If your code is working for some objects and not others then there must be
something different in the object it is not working in.
Please include your merge code, and the code for the class it does not
work in, its superclass, and one of the classes it does work in.
---
James
|
|
|
Re: @Version field does partially update? [message #387097 is a reply to message #387070] |
Wed, 15 April 2009 14:41 ![Go to previous message Go to previous message](theme/Solstice/images/up.png) ![Go to next message Go to next message](theme/Solstice/images/down.png) |
Eclipse User![Friend of Eclipse Friend](/donate/web-api/friends_decorator.php?email=) |
|
|
|
Hi James,
This is the Superclass:
8<-------------------------------------------------
package ch.eugster.colibri.persistence.entities;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.persistence.Version;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
@MappedSuperclass
@ObjectTypeConverter(name = "booleanConverter", dataType =
java.lang.Short.class, objectType = java.lang.Boolean.class,
conversionValues =
{ @ConversionValue(dataValue = "0", objectValue = "false"),
@ConversionValue(dataValue = "1", objectValue = "true") },
defaultObjectValue = "false")
public abstract class AbstractEntity
{
protected static long counter = 0l;
public static boolean DEBUG = true;
protected static void out(String output)
{
if (AbstractEntity.DEBUG)
{
System.out.println(output);
}
}
protected static void err(String error)
{
System.err.println(error);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
protected long timestamp;
@Convert("booleanConverter")
protected boolean deleted;
@Version
protected int version;
@Transient
protected PropertyChangeSupport propertyChangeSupport = new
PropertyChangeSupport(this);
public AbstractEntity()
{
}
public Long getId()
{
return this.id;
}
public void setId(Long id)
{
this.propertyChangeSupport.firePropertyChange("id", this.id, this.id =
id);
}
public long getTimestamp()
{
return this.timestamp;
}
public void setTimestamp(long timestamp)
{
this.propertyChangeSupport.firePropertyChange("timestamp",
this.timestamp,
this.timestamp = timestamp);
}
public boolean isDeleted()
{
return this.deleted;
}
public void setDeleted(boolean deleted)
{
this.propertyChangeSupport.firePropertyChange("deleted", this.deleted,
this.deleted = deleted);
}
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener)
{
this.propertyChangeSupport.addPropertyChangeListener(propert yName,
listener);
}
public void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener)
{
this.propertyChangeSupport.removePropertyChangeListener(prop ertyName,
listener);
}
public int getVersion()
{
return this.version;
}
public void setVersion(int version)
{
this.version = version;
}
protected String getString(String string)
{
return string == null ? "" : string;
}
@Override
public int hashCode()
{
if (this.id == null)
return Integer.MIN_VALUE;
else
{
return Integer.MIN_VALUE + this.id.intValue();
}
}
@Override
public boolean equals(Object object)
{
if (object == null) return false;
if (this.getClass().equals(object.getClass()))
{
AbstractEntity bt = (AbstractEntity) object;
return this.hashCode() == bt.hashCode();
}
return false;
}
}
8<-------------------------------------------------
And this is the class that fails to merge after the first merge:
8<-------------------------------------------------
/*
* Created on 17.12.2008
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package ch.eugster.colibri.persistence.entities;
import static javax.persistence.CascadeType.ALL;
import static javax.persistence.FetchType.EAGER;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@AttributeOverrides(
{
@AttributeOverride(name = "id", column = @Column(name = "tab_id",
updatable = false, unique = true)),
@AttributeOverride(name = "version", column = @Column(name =
"tab_version")),
@AttributeOverride(name = "timestamp", column = @Column(name =
"tab_timestamp")),
@AttributeOverride(name = "deleted", column = @Column(name =
"tab_deleted")) })
@Table(name = "colibri_tab")
public class Tab extends AbstractEntity implements Comparable<Tab>
{
@ManyToOne(cascade = ALL)
@JoinColumn(name = "tab_configurable_id", referencedColumnName =
"configurable_id")
private Configurable configurable;
@Basic
@Column(name = "tab_name")
private String name;
@Basic
@Column(name = "tab_rows")
private int rows;
@Basic
@Column(name = "tab_cols")
private int cols;
@Basic
@Column(name = "tab_pos")
private int pos;
@OneToMany(cascade = CascadeType.ALL, fetch = EAGER, mappedBy = "tab")
private Collection<Key> keys = new ArrayList<Key>();
public Tab()
{
super();
}
public Tab(Configurable configurable)
{
super();
this.setConfigurable(configurable);
}
public Configurable getConfigurable()
{
return this.configurable;
}
public void setConfigurable(Configurable configurable)
{
this.propertyChangeSupport.firePropertyChange("configurable ",
this.configurable,
this.configurable = configurable);
}
public String getName()
{
return this.getString(this.name);
}
public void setName(String name)
{
this.propertyChangeSupport.firePropertyChange("name", this.name,
this.name = name);
}
public int getRows()
{
return this.rows;
}
public void setRows(int rows)
{
this.propertyChangeSupport.firePropertyChange("rows", this.rows,
this.rows = rows);
}
public int getCols()
{
return this.cols;
}
public void setCols(int cols)
{
this.propertyChangeSupport.firePropertyChange("cols", this.cols,
this.cols = cols);
}
public int getPos()
{
return this.pos;
}
public void setPos(int pos)
{
this.propertyChangeSupport.firePropertyChange("pos", this.pos, this.pos
= pos);
}
public Collection<Key> getKeys()
{
return this.keys;
}
public void addKey(Key key)
{
if (key != null)
if (!this.keys.contains(key))
this.propertyChangeSupport
.firePropertyChange("keys", this.keys, this.keys.add(key));
}
public void removeKey(Key key)
{
if (key != null)
if (this.keys.contains(key))
this.propertyChangeSupport.firePropertyChange("keys", this.keys,
this.keys
.remove(key));
}
public void setKeys(Collection<Key> keys)
{
this.propertyChangeSupport.firePropertyChange("keys", this.keys,
this.keys = keys);
}
public int compareTo(Tab other)
{
return other.getPos() - this.getPos();
}
}
8<-------------------------------------------------
And this is a class that merges successfully:
8<-------------------------------------------------
/*
* Created on 17.12.2008
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package ch.eugster.colibri.persistence.entities;
import static javax.persistence.CascadeType.ALL;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@AttributeOverrides(
{
@AttributeOverride(name = "id", column = @Column(name = "stock_id",
updatable = false, unique = true)),
@AttributeOverride(name = "version", column = @Column(name =
"stock_version")),
@AttributeOverride(name = "timestamp", column = @Column(name =
"stock_timestamp")),
@AttributeOverride(name = "deleted", column = @Column(name =
"stock_deleted")) })
@Table(name = "colibri_stock")
public class Stock extends AbstractEntity
{
@ManyToOne(cascade = ALL)
@JoinColumn(name = "stock_salespoint_id", referencedColumnName =
"salespoint_id")
private Salespoint salespoint;
@ManyToOne(cascade = ALL)
@JoinColumn(name = "stock_payment_type_id", referencedColumnName =
"payment_type_id")
private PaymentType paymentType;
@Basic
@Column(name = "stock_amount")
private double amount;
@Basic
@Column(name = "stock_variable")
private boolean variable;
public Stock()
{
super();
}
public Stock(Salespoint salespoint)
{
super();
this.setSalespoint(salespoint);
}
public Stock(Salespoint salespoint, PaymentType paymentType)
{
this.setSalespoint(salespoint);
this.setPaymentType(paymentType);
}
public Salespoint getSalespoint()
{
return this.salespoint;
}
public void setSalespoint(Salespoint salespoint)
{
this.propertyChangeSupport.firePropertyChange("salespoint",
this.salespoint,
this.salespoint = salespoint);
}
public PaymentType getPaymentType()
{
return this.paymentType;
}
public void setPaymentType(PaymentType paymentType)
{
this.propertyChangeSupport.firePropertyChange("paymentType",
this.paymentType,
this.paymentType = paymentType);
}
public double getAmount()
{
return this.amount;
}
public void setAmount(double amount)
{
this.propertyChangeSupport.firePropertyChange("amount", this.amount,
this.amount = amount);
}
public boolean isVariable()
{
return this.variable;
}
public void setVariable(boolean variable)
{
this.propertyChangeSupport.firePropertyChange("variable", this.variable,
this.variable = variable);
}
}
8<-------------------------------------------------
The code to update the objects is in the editor and as follows:
8<-------------------------------------------------
@Override
public void doSave(IProgressMonitor monitor)
{
if (this.validate())
{
this.saveValues();
AbstractEntityEditorInput input = (AbstractEntityEditorInput)
this.getEditorInput();
AbstractEntity entity = input.getEntity();
try
{
if (input.hasParent())
{
Repository.getCurrent().store(entity, true);
Repository.getCurrent().refresh(input.getParent());
}
else
Repository.getCurrent().store(entity);
this.setDirty(false);
this.scrolledForm.setText(this.getText());
this.updateControls();
}
catch (PersistenceException e)
{
if (e.getErrorCode().equals(PersistenceException.ErrorCode.SQL_ 4002))
{
Shell shell = this.getSite().getShell();
Message msg = this.getMessage(e.getErrorCode());
new MessageDialog(shell, msg.getTitle(), null, msg.getMessage(),
MessageDialog.WARNING, new String[]
{ Messages.AbstractEntityEditor_ok }, 0).open();
this.setFocus(msg.getControl());
}
}
}
}
The called method of the previous method (store):
public void store(AbstractEntity entity, boolean silent, boolean
updateTimestamp)
throws PersistenceException
{
try
{
boolean tx = this.beginTransaction();
WriteType type = this.doStore(entity, updateTimestamp);
if (tx) this.commitTransaction();
if (!silent) this.repository.fireWriteDatabaseEvent(new
WriteEvent(entity, type));
}
catch (Exception e)
{
e.printStackTrace();
Throwable cause = e.getCause();
if (cause instanceof DatabaseException)
{
DatabaseException de = (DatabaseException) cause;
throw new PersistenceException(de);
}
else if (cause instanceof javax.persistence.OptimisticLockException)
{
org.eclipse.persistence.exceptions.OptimisticLockException ole =
(org.eclipse.persistence.exceptions.OptimisticLockException) cause
.getCause();
throw new PersistenceException(ole);
}
}
finally
{
this.rollbackTransaction();
}
}
8<-------------------------------------------------
and the code that updates (merges) the object is as follows:
8<-------------------------------------------------
private WriteType doStore(AbstractEntity entity, boolean updateTimestamp)
{
if (updateTimestamp)
entity.setTimestamp(GregorianCalendar.getInstance().getTimeI nMillis());
if (entity.getId() == null)
{
this.entityManager.persist(entity);
return WriteType.INSERT;
}
else
{
this.entityManager.merge(entity);
return WriteType.UPDATE;
}
}
8<-------------------------------------------------
I hope that that helps you to see into my code...
Thank you
Christian
|
|
| |
Goto Forum:
Current Time: Mon Feb 10 11:57:11 GMT 2025
Powered by FUDForum. Page generated in 0.05208 seconds
|