jakartaee / persistence

https://jakartaee.github.io/persistence/
Other
204 stars 59 forks source link

Allow @GeneratedValue for non-@Id fields #113

Open lukasj opened 9 years ago

lukasj commented 9 years ago

Hello,

My scenario is the following - I have a tt>@MappedSuperclass</tt 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 tt>@GeneratedValue</tt is used together with tt>@Id</tt. My proposal is to allow it to be used on columns that are not tt>@Id</tt.

lukasj commented 6 years ago
lukasj commented 9 years ago

@glassfishrobot Commented Reported by paranoiabla

lukasj commented 8 years ago

@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;
lukasj commented 8 years ago

@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

lukasj commented 8 years ago

@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

lukasj commented 8 years ago

@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.

lukasj commented 8 years ago

@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

lukasj commented 8 years ago

@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.

lukasj commented 8 years ago

@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!

lukasj commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA JPA_SPEC-113

lukasj commented 6 years ago

@nithisathish Commented @Entity public class SequenceNumber { @Id @GeneratedValue(...) private Long number; }

@Entity public class Entity { @Id .. private Long id;

@OneToOne(...) private SequnceNumber val; }

thejeff77 commented 5 years ago

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

sumitdhungana14 commented 3 years ago

Do we have any updates on this? @GenericGenerator doesn't generate values for columns other than the @Ided column.

sebersole commented 3 years ago

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.

asariev commented 3 years ago

Agree with @sebersole!

gavinking commented 1 year ago

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.

hendisantika commented 5 months ago

This is still open ya?

Or is it closed?

How do we fix it?

Thanks

rikes commented 2 months ago

In my case I needed to include a field whose value was generated by a sequence in the Oracle database.

Adding Generated from Hibernate worked

@Generated(GenerationTime.INSERT)
@Column(name = "my_field")
private Long field;

Source: https://stackoverflow.com/a/23831524