persistence
persistence copied to clipboard
Allow @GeneratedValue for non-@Id fields
Hello,
My scenario is the following - I have a @MappedSuperclass which defines a field pk (which is generated value with a custom generic generator) but I also have an entity called Order with a property code. I have created a custom generic generator which calculates on the server what the order code must be, but even though I have specified it as this:
@Column(name = "code", nullable = false)
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
private String code;
This generator is never called. I checked the javadoc and there explicitly says that the @GeneratedValue is used together with @Id. My proposal is to allow it to be used on columns that are not @Id.
- Issue Imported From: https://github.com/javaee/jpa-spec/issues/113
- Original Issue Raised By:@glassfishrobot
- Original Issue Assigned To: @ldemichiel
@glassfishrobot Commented Reported by paranoiabla
@glassfishrobot Commented j0ke said: @GenericGenerator is hibernate specific annotation, however it will be nice to have similar way in JPA ( or GenericType (again from hibernate), maybe we should submit a new request for that ?
However I vote that will be nice if this works :
//@Id without ID since we have a different PK in this entity already which is the @Id .. likepk or something. @GeneratedValue(strategy=GenerationType.TABLE, generator="orderGenerator")
@TableGenerator(
name="orderGenerator",
table="GENERATOR_TABLE",
pkColumnName = "key",
valueColumnName = "next",
pkColumnValue="order_number",
allocationSize=30)
private String orderNumber;
@glassfishrobot Commented neilstockton said: Since this issue is about allowing GeratedValue to be used on non-PK fields then yes you most certainly have to create that on a separate issue. And while doing so, state what you want it for, because just saying "I want something like this Hibernate annotation" is saying absolutely nothing about why you think something should become a standard
@glassfishrobot Commented
j0ke said:
I Agree but for now I will be very happy if the @GeneratedValue does not require @Id.
Otherwise why we have 2 annotations, we can have an attribute in the Id saying "strategy" and "generator" as optional, having it like this 2 annotations that kinda work magically only together looks bad.
About the GenericGenerator and GeneratorType (both from Hibernate) we indeed should discuss in separate issue and of course I will not say "because Hibernate have them", you can trust me I am an engineer !
Nayden
@glassfishrobot Commented ngagov said: It will be good if we could generate values for non- @Id columns via standard JPA annotations, simply because not only the @Id columns might require custom value generation. May be in JPA we could have separate annotations just like @GeneratorType and @ValueGenerationType in Hibernate, which allows generation of values for non-@Id columns.
@glassfishrobot Commented neilstockton said: I don't see why you need "GeneratorType" or "ValueGenerationType" annotations (whatever they do) ... you simply need an implementation to support @GeneratedValue on the field; no need to complicate things for no defined benefit. If you think some other annotation is needed, then state what you think that is adding and why it is needed
@glassfishrobot Commented j0ke said: @neilstockton yes indeed @GeneratedValue can be supported by some implementation but why should it be just supported by implementation instead of support in the spec ? About the "other" annotation you may want a non numeric PK generation. For example for shippings or orders it doesn't make sense to have your order id is 12012 or your shipping is 23123321 it make sense to have a class/strategy that can provide the PK/ID value so you may have an ID like
${MERCHANTID}-${CLIENTID}-${ORDERNumberPerThisClient}
and so on as PK not just Sequence, auto increment or table with PK nextvals.
@glassfishrobot Commented neilstockton said: My comment was to the previous poster (ngagov), and nowhere have I said @GeneratedValue should not be on non-PK fields ... in fact I said I totally support that being in the standard (and I already use that in the implementation I use which does support it on non-PKs)!
I asked what are these other annotations, and why should the standard have them? I repeat the point i made to you earlier (which you are supposed to raise in a separate issue) ... if you are going to PROPOSE something, then kindly explain WHAT role it performs. If you want non-numeric PK generation, like some implementations do with things like "UUID" then you can define the column type ... but there's no need of a special annotation for that, since you already have @Column!
@glassfishrobot Commented This issue was imported from java.net JIRA JPA_SPEC-113
@nithisathish Commented @Entity public class SequenceNumber { @Id @GeneratedValue(...) private Long number; }
@Entity public class Entity { @Id .. private Long id;
@OneToOne(...) private SequnceNumber val; }
Is there any update on this? The annotations still don't seem to be working without additional annotations such as Id. I've tried options from the post below excluding extra Id or column annotations and the field is not generated.
https://stackoverflow.com/questions/47934661/generate-unpredictable-random-id-for-entity
Do we have any updates on this? @GenericGenerator
doesn't generate values for columns other than the @Id
ed column.
I think this would be a good addition. But if not already a separate request, I suggest we consider how this plays with update/insert handling. I assume the intention here is specifically for insertion-time generation. However, update-time generators are plenty useful as well - modified-timestamp e.g.
I'd actually suggest not re-using @GeneratedValue
here, which is really a shame because that name really fits better for this non-id case. But regardless, for the sake of discussion let's call it @GeneratedNonIdValue
... something like:
@interface GeneratedNonIdValue {
enum Timing { INSERT, UPDATE, BOTH }
Timing timing() default BOTH;
GenerationType strategy() default AUTO;
String generator() default "";
}
Depending on how robust and flexible we want to make this, I'd also suggest having a look at https://github.com/hibernate/hibernate-orm/blob/main/hibernate-core/src/main/java/org/hibernate/tuple/ValueGeneration.java It illustrates some things I've had to deal with implementing this for Hibernate over the years.
Agree with @sebersole!
I think this would be a good addition. But if not already a separate request, I suggest we consider how this plays with update/insert handling. I assume the intention here is specifically for insertion-time generation. However, update-time generators are plenty useful as well
Indeed. If we do this, we should go the whole hog and do this issue, #342, and update-time generation all at once.
Note that there's an existing issue, #51, which proposes using @PrePersist
and @PreUpdate
annotations to identify insert-time and update-time generation. Since we actually already have those annotations, that's actually a pretty interesting idea, and I sorta like it.
@PrePersist @GeneratedValue Instant created;
@PrePersist @PreUpdate @GeneratedValue Instant updated;
That's not awful at all. (It's superficially a bit different to the track we took with the generator framework in Hibernate, but it's not at all inconsistent with the ideas there.)
Anyway, I actually want to close #51 because the proposal there is written up in a very weird way, and it's had no activity, but I'm recording the idea here, since it's a possible approach we could take if/when we decide to address this issue, probably in conjunction with #342.
This is still open ya?
Or is it closed?
How do we fix it?
Thanks