0
class Extra { int a; } @Entity @Table(name = "data_table") @Data class Data { @Column int state; @Column(name = "extra") String _extra; @Transient Extra extra; @PostLoad void preLoad() { extra = mapper.readValue(_extra, Extra.class); } @PrePersist @PreUpdate void prePersist() { _extra = mapper.writeValueAsString(extra); } } Data data = jpaRepository.findOne(...); data.setState(1); data.getExtra().setA(1); jpaRepository.save(data); 

I want to use extra string column as Extra object. So I made @PostLoad, @PrePersist callbacks, which are converting extra column. But, when I persist data object, state value is persisted, but extra column (Data._extra) is not persisted. What did I do wrong?

2
  • 1
    Why not use a converter on the Extra mapping instead of making it transient? The converter would convert it to/from a string instead of relying on the preLoad and prePersist methods, and allow you to remove the _extra field. See docs.oracle.com/javaee/7/api/javax/persistence/Convert.html Commented Jun 21, 2017 at 14:47
  • Currently, I'm using converter. Now I'm just wondering why extra column is not persisted. Commented Jun 21, 2017 at 15:52

3 Answers 3

3

Your defined extra object is @Transient. Transient objects aren't saved to DB.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, I meant extra column. (_extra member of Data)
1

Your save method - is it using merge? Since Extra is transient, it is invisible to JPA and would not be merged into the managed instance. So it will be null when the preUpdate method is called. you'll have to write your own save method to merge in transient values if you need them.

Comments

1

If you really meant to ask about extra.a then the answer of @Abdullah G if right.

But if you made a typo then you probably meant _extra field.

Hibernate caches the value just being persisted so you're getting a cached old object in @PreUpdate callback.

UPDATE The solution I've found is to use

@Column(name = "password", insertable = false, updatable = false) 

instead of @Transient annotation. However, it creates a column in the database that is always null.


2 Comments

I couldn't understand. Do you mean that extra in prePersist() is old object? But I set extra with data.getExtra().setA(1). How could it be..?
@chaeyk data object itself is old. you can even see it in a debugger. I've found this issue and checked myself. when you view the extra field the second time, it is not changed while the state is. so before call to dataRepository.save(data) I see the extra field is changed but when I debug in @PreUpdate - it is not

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.