I have an entity class that contains a map of key-value pairs which live in a different table and there may be no such pairs for a given entity. The relevant code for the entity classes is below.
Now, when I insert such an entity with persist()
, then add key-value pairs, and then save it with merge()
, I get duplicate entry errors for the related table that stores the key-value pairs. I tried to hold back insertion until the keys were added, to have one call to persist()
only. This led to duplicate entry errors containing an empty (zero) id in the foreign key column (ixSource
).
I followed the process in the debugger, and found that eclipselink seems to be confused about the cascading. While it is updating the entity, it executes calls that update the related table. Nonetheless, it also adds those operations to a queue that is processed afterwards, which is when the duplicate entry errors occur. I have tried CascadeType.ALL
and MERGE
, with no difference.
I'm using static weaving, if it matters.
Here's the entities`code, shortened for brevity:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "sType")
@Table(name = "BaseEntity")
public abstract class BaseEntity extends AbstractModel
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ix")
private long _ix;
}
@Entity
@Table(name = "Source")
public class Source extends BaseEntity
{
@OneToMany(cascade = CascadeType.MERGE)
@JoinTable(name = "SourceProperty", joinColumns = { @JoinColumn(name = "ixSource") })
@MapKey(name = "sKey")
private Map<String, SourceProperty> _mpKeys;
// ... there's more columns that probably don't matter ...
}
@Entity
@Table(name = "SourceProperty")
@IdClass(SourcePropertyKey.class)
public class SourceProperty
{
@Id
@Column(name = "sKey", nullable = false)
public String sKey;
@Id
@Column(name = "ixSource", nullable = false)
public long ixSource;
@Column(name = "sValue", nullable = true)
public String sValue;
}
public class SourcePropertyKey implements Serializable
{
private final static long serialVersionUID = 1L;
public String sKey;
public long ixSource;
@Override
public boolean equals(Object obj)
{
if (obj instanceof SourcePropertyK开发者_运维问答ey) {
return this.sKey.equals(((SourcePropertyKey) obj).sKey)
&& this.ixSource == ((SourcePropertyKey) obj).ixSource;
} else {
return false;
}
}
}
I can't see how those errors would occur. Could you include the SQL and ful exception.
What version of EclipseLink are you using, did you try the latest release?
Why are you calling merge? Are you detaching the objects through serialization, if it is the same object, you do not need to call merge.
It could be an issue with the @MapKey, does it work if you remove this?
精彩评论