Search code examples
javajpaeclipselink

Embedded AttributeOverride on update not working


I have entity with embedded two ModelId classes, where one is EmbeddedId and the other references another entity.

@Entity
public class Report implements Serializable {

    @EmbeddedId
    private final ModelId id;

    @AttributeOverride(name = "id", column = @Column(name = "scheme_id")
    @Embedded
    private ModelId schemeId;

    public void changeScheme(ModelId schemeId) {
        this.schemeId = schemeId;
    }
}

@Embeddable
public class ModelId implements Serializable {

    private Integer id;
}

I can insert and select Report but when I update the field schemeId I get:

org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [mypackage.ModelId] is mapped
to a primary key column in the database. Updates are not allowed.

I use GlassFish 4.1 with EclipseLink 2.5.

Am I missing something or is it EclipseLink bug?


The problem is that only id makes primary key, schemeId is foreign key. When I change schemeId to association it works fine:

@ManyToOne
@JoinColumn(name = "scheme_id", referencedColumnName = "id")
private Scheme scheme;

public void changeScheme(Scheme scheme) {
    this.scheme = scheme;
}

I've been testing with many annotation combinations and also in GF4.0 and EclipseLink 2.6 with same result.

It seems like EclipseLink is ignoring @AttributeOverride during update and is mixing inner schemeId.id with id.id.


Solution

  • We had the same issue. It would appear that this defect is covered by an existing bug for eclipselink (against version 2.6.0, I still see this issue in 2.6.3):

    https://bugs.eclipse.org/bugs/show_bug.cgi?id=477638

    It doesn't appear that there is any activity on this yet, so in the meantime I changed the @EmbeddedId to be just @Embedded and added a private primary key instead, like so:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int privateId;
    

    I also added a composite unique constraint for the properties that were formerly part of the primary key. I had to change my EntityManager.find(dataType, id) calls as well to do a query instead. I hope this helps.