Updating a reference to a FK

615 Views Asked by At

I've searched for quite a while trying to figure this out. I am using JPA with EclipseLink (Oracle DB). I have a lookup table full of values. I have another table that has a FK relationship to that table. I can insert data fine, but when I try to update the table with a different value, I get an exception. I've tried setting the CASCADE_TYPE but that doesn't have any impact. I thought this would be simple, but maybe I'm missing something.

Lookup table:

public class SomeType implements Serializable {
    @Id
    @Column(name = "ID")
    private Short id;

    @Column(name = "TYPE")
    private String type;

    :
    (getters & setters)
}

Contents:

ID     Type
------------
1     Type1
2     Type2
3     Type3
:       :

Person table (I've left out the Sequencing stuff for brevity):

public class Person implements Serializable {
    @Id
    @Column(name = "ID")
    private Short id;

    @JoinColumn(name = "SOME_TYPE", referencedColumnName = "ID")
    @ManyToOne(optional = false)
    private SomeType someType;

    :
    (getters & setters)
}

Inserting works fine:

EntityManager em;
:
Person p = new Person();
p.setSomeType(new SomeType(1));
em.persist(p);

That results in:

ID      SOME_TYPE
------------------
1         1

But if I want to update Person to change the type:

EntityManager em;
:
Person p = em.find(1);
SomeType newtype = new SomeType(2);
p.setSomeType(newtype);
em.merge(p);

I see the following exception:

Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [SomeType] is mapped to a primary key column in the database. Updates are not allowed.

All I want is the value in the Person table to be updated, like:

UPDATE PERSON set SOME_TYPE = 2 where ID = 1;

Any assistance would be greatly appreciated. Thanks.

1

There are 1 best solutions below

0
On

Thanks to Chris for answering this: The update is possible if you use a reference to the managed instance of the object that you want to refer to, not create a new instance.

Person p = em.find(1);
p.setSomeType(em.find(SomeType.class, 2));
em.merge(p);