简体   繁体   中英

How to use EntityManager from @PrePersist?

I have "post" entity/table with this "schema":

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
int id;

@GeneratedValue(strategy = GenerationType.AUTO)
private Integer postId;

private Integer revisionId;
private Boolean isCurrentRevision;

So, table contains posts, each of them has multiple revisions, but only of them (for each post) is current.

Now, let's say I want to persist another revision of existing post (ie update post):

I need to find highest existing revisionId for this postId, increment it and set it to revisionId. Also this is the new current revision and so it should be marked accordingly, but also the former current revision should be unmarked.

But how can I do this? I feel that this should really be part of entity implementation but on the other hand I need EntityManager to do this. But I can't find a way to inject EntityManager instance (which is guaranteed to exist).

Is it possible? How do you implement such scenarios? Thanks!

Unfortunately, there is no clean, portable way to what you propose. The JPA 2 specification ( JSR 317 ) states the following:

In general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context.

As far as implementations go, Hibernate forbids it explicitly:

A callback method must not invoke EntityManager or Query methods!

I know it's not really what you were hoping for, but it seems that you will have to allocate the revision management responsibility to the clients of your entity class.

This might be a good place for the transfer object pattern. We normally do it like this:
1. convert the post entity to a post transfer object
2. once the post is saved we'd select the highest revisionId, increment it and create a new entity

Alternatively, you could update the current post and add an entry to a history table (possible even in a separate database). Thus you could keep the post table as small as possible for better performance since most of the time the current version of a post would be required anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM