I have a fairly simple problem. In a single transaction, my code looks something like this:
MyClass c = new MyClass();
c.setPropA("A");
c = myClassRepository.save(c);
c.setPropC("C");
Where my entity looks like this:
@Entity
@Table(name = "MY_CLASS")
public class MyClass {
private String propA;
private String propB;
private String propC;
@Id
@Column(name = "PROP_A", unique = true, nullable = false, updatable = false)
public String getPropA() { return propA; }
public void setPropA(String propA) { this.propA = propA; }
@Column(name = "PROP_B", insertable = false)
public String getPropB() { return propB; }
public void setPropB(String propB) { this.propB = propB; }
@Column(name = "PROP_C")
public String getPropC() { return propC; }
public void setPropC(String propC) { this.propC = propC; }
}
And the database is set up like this (Dialect = Oracle 11G)
CREATE TABLE MY_CLASS {
PROP_A VARCHAR2 NOT NULL PRIMARY KEY,
PROP_B VARCHAR2 DEFAULT 'B' NOT NULL,
PROP_C VARCHAR2
}
So, based on the code to persist the entity, I would think I'd get queries that look something like this:
MyClass c = new MyClass();
c.setPropA("A");
c = myClassRepository.saveAndFlush(c);
// INSERT INTO MY_CLASS (PROP_A, PROP_C) VALUES ("A", NULL)
// SELECT PROP_A, PROP_B, PROP_C FROM MY_CLASS -- to refresh `c`
c.setPropC("C");
// After transaction ends, flush change to `c.propC`
// UPDATE MY_CLASS SET PROP_B = "B", PROP_C = "C" WHERE PROP_A = "A"
... but the SELECT
never happens. Why is the entity not refreshed?
This breaks because of the UPDATE
that (immediately) follows the INSERT
and c.propB
is still null
. I get a ORA-01407: cannot update ("MY_SCHEMA"."MY_CLASS"."PROP_B") to NULL
stack trace.
I realize there are ways around this using @PrePersist
or setting default values on columnDefinition
in Java, but I shouldn't have to duplicate defaults.
Note: This worked before when I was using org.hibernate.Session.saveOrUpdate()
instead of Spring Data JPA for this action.
Thanks in advance for any help!
JPA's persist method returns void and Hibernate's save method returns the primary key of the entity.
Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.
Hibernate doesn't know that B is generated by the database, and that it has to read it after insert, unless you tell it to do so using the @Generated
annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With