Type: New Feature
Affects Version/s: None
Fix Version/s: None
Almost every no-nonsense business application (hence JPA application in the context of this issue) is in the need to support automatic values, i. e. values provided by JPA automatically without the support of a higher layer. Currently JPA only supports one type of automatic value: Generated IDs. For more convenient support of business applications it would be great if JPA could provide automatic values for more cases:
- @CurrentUser to inject the current user to a data field (this is what databases do with the CURRENT USER constraint). As in the Java EE environment there is a difference between security principals, business layer people, and database accounts, there should be a mapping available. For example "@CurrentUser(type = PRINCIPAL_NAME) String createdBy" would default the content of "createdBy" to the name of the caller principal's name. This is the most common need for automatic values in business applications.
- @CurrentTimestamp to inject the current timestamp of a transaction into a data field. The annotation will guarantee that at the transaction start the timestamp is produced once, so all uses of the annotation within the same annotation will guarantee to inject the same timestamp value. This is another essential business need, as sometimes transactions run rather long, but all written data shall have synchronized timestamps.
- @QuerySingleResult(ejbql = "JPAQL QUERY" | namedQuery = "name of query") to inject the .getSingleResult() output of either a given JPAQL query or of a named query into a field annotated with this annotation. This is often needed in business applications, for example if the written data is dependend of a aggregate other entities. This is what a trigger would do in databases.
- @PrePersist / @PreUpdate / @PostPersists / @PostUpdate annotations are used to define the event when the above annotations are to be injected. @PrePersist will be the most typical use case.
As an alternative to this approach, all of the above could be solved easily with an entity listener, if it would be possible to inject an entity manager into it. While this would be the more flexible solution, it would also imply more complexity to the application's source code. Especially @CurrentUser is rather complex to implement, as it implies using ThreadLocal and / or TransactionSynchronizationRegistry to forward the current user from the EJB layer to the JPA layer. Also, this solution would be Java EE only, while @CurrentUser could be easily made Java SE, too, e. g. by providing a standard entity manager factory property "javax.persistence.currentuser" which defaults to "javax.persistence.jdbc.user".
|4.||@PrePersist / @PreUpdate / @PostPersist / @PostUpdate||Open||Unassigned|