JPA autoincrement non primary key column - jpa

How can i auto increment a non primary column using annotations.
I tried this but it is not working.
#Generated(value="GenerationTime.INSERT")
#GenericGenerator(name="id", strategy="sequence")
private Long id;
I am using mysql database

JPA specification only provides for "id" fields to have their values generated. Any other fields are not supported. Some implementations (e.g DataNucleus JPA) support value generation on any field, but that is a vendor extension.
You could use prePersist callback and hook something in yourself if your provider doesn't support it
PS those annotations you use are NOT JPA annotations

Related

Generate Hibernate Envers primary key manually and jpa as well

My project is migrating from Grails to Java so I have exisiting Audit data in a single table pushed by Grails Audit plugin, now I am using Java envers for Auditing in java. I have below doubts:
-> If i want to push data from single table to different Audit tables(in Java) manually, how can i generate Primary key of revision table for history data manually which will not collide with primary key generated from Java annotation?
As for new entries I am generating primary key like below:
#Id
#GeneratedValue
#RevisionNumber
#Column(name = "ID") #NotNull
private Long revisionId;
-> Any other way to push data from single audit table to segregated Audit tables(In java) instead of doing it manually?
Please let me know about this.
Thanks.
Envers should be creating sequence named REVISION_LISTENER on Oracle.
Therefore you should be able to use Oracle's syntax SELECT REVISION_LISTENER.NEXTVAL in order to get the next sequence value and use that in the REV field both in your audit table and the revision entity info table too.
This only applies to DefaultAuditStrategy.
If you intend to use the ValidityAuditStrategy, there are other fields which you'll have to understand the internals of Envers in order to be able to populate the relevant fields. If you are using this strategy, let me know and I'll add more details that are specific to it, but its very complex and quite tedious.

JPA and PostgreSQL with GenerationType.IDENTITY

I have a question about Postgres and GenerationType.Identity vs Sequence
In this example...
#Id
#SequenceGenerator(name="mytable_id_seq",
sequenceName="mytable_id_seq",
allocationSize=1)
#GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="mytable_id_seq")
I understand that I am specifying a Postgres sequence to use via annotations.
However, I have an id column defined with the 'serial' type, I have read that I can simply use GenerationType.IDENTITY and it will automatically generate a db sequence and use it to auto increment.
If that's the case, I don't see an advantage to using the SEQUENCE annotations unless you are using an integer for an id or have some specific reason to use another sequence you have created. IDENTITY is alot less code and potentially makes it portable across databases.
Is there something I'm missing?
Thanks in advance for the feedback.
If you have a column of type SERIAL, it will be sufficient to annotate your id field with:
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
This is telling Hibernate that the database will be looking after the generation of the id column. How the database implements the auto-generation is vendor specific and can be considered "transparent" to Hibernate. Hibernate just needs to know that after the row is inserted, there will be an id value for that row that it can retrieve somehow.
If using GenerationType.SEQUENCE, you are telling Hibernate that the database is not automatically populating the id column. Instead, it is Hibernate's responsibility to get the next sequence value from the specified sequence and use that as the id value when inserting the row. So Hibernate is generating and inserting the id.
In the case of Postgres, it happens that defining a SERIAL column is implemented by creating a sequence and using it as a default column value. But it is the database that is populating the id field so using GenerationType.IDENTITY tells Hibernate that the database is handling id generation.
These references may help:
http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators
https://www.postgresql.org/docs/8.1/static/datatype.html#DATATYPE-SERIAL
From "Pro JPA2" book:
"Another difference, hinted at earlier, between using IDENTITY and other id generation strategies is that the identifier will not be accessible until after the insert has occurred. Although no guarantee is made about the accessibility of the identifier before the transaction has completed, it is at least possible for other types of generation to eagerly allocate the identifier. But when using identity, it is the action of inserting that causes the identifier to be generated. It would be impossible for the identifier to be available before the entity is inserted into the database, and because insertion of entities is most often deferred until commit time, the identifier would not be available until after the transaction has been committed."
I think it can be helpful if you are using the same sequence for more than one table (for example you want a unique identifier for many types of bills) ... also If you want to keep track of the sequence away from the auto generated key
You can find here the solution of updating the PostgreSQL table creation accordingly, in order to work with the GenerationType.IDENTITY option.

Spring Roo Database Reverse Engineering (DBRE) support for column names with reserved words?

I am using Spring Roo to reverse engineer a mysql database scheme in which reserved names (accessible, key, ...) are used for columns names. I am using EclipseLink as JPA implementation.
The data base queries generated for these fields are causing an SQL error since the conflicting field names are not enclosed in back ticks.
In order to avoid these errors the name in the JPA #Column annotation should be quoted like:
#Column(name = "\"accessible\"")
Other roo commands provide the --permitReservedWords option, the database reverse engineer command seems to be missing this.
Are column names with reserved words not supported by DBRE?

Required attribute for foreign keys

I'm just thinking about a foreign key attribute in Entity Framework (using code first approach).
I want to ensure that this foreign key is always set, in other words: It should be required.
Is using the "Required"-attribute/data annotation a clean solution for this? Or should this data annotation be used for user input only?
I don't think you need to have required attribute in the data annotation . If you have declared it as
public int ForeignKeyName{get;set;}
It will take as required by EF. And if it
public int? ForeignKeyName{get;set;}
it will be taken as optional(nullable) by entity framework Conventions . I'm not sure what kind of framework you are using for the web(front end Ex: asp.net mvc). Depend on that you need to think about that input level.

JPA SequenceGenerator and GeneratedValue: name / generator property unique only per class?

I use JPA + OpenJPA with PostgreSQL as backend RDBMS. The primary keys of my tables usually consist of a SERIAL / BIGSERIAL column. So PostgreSQL automatically generates IDs for new entries (strategy=GenerationType.IDENTITY).
The annotations of ID property look like this:
#Id
#SequenceGenerator(name="myseq",sequenceName="foobartable_fooid_seq")
#GeneratedValue(generator="myseq",strategy=GenerationType.IDENTITY)
My question is: Can I copy and paste this annotations block to several entities, while only modifying the sequenceName value? The sequenceName is different from table to table. But may the SequenceGenerator of all Entities be named myseq or something like that? Or does one have to specify a unique generator name for the SequenceGenerator of each Entity? So that each SequenceGenerator name must be unique in the persistence unit?
Is it possibly a good idea to use the same value used for the sequenceName in the database? So that I'd write something like
#Id
#SequenceGenerator(name="foobartable_fooid_seq",sequenceName="foobartable_fooid_seq")
#GeneratedValue(generator="foobartable_fooid_seq",strategy=GenerationType.IDENTITY)
Any recommendations on how to name the SequenceGenerators?
Many thanks in advance for any suggestions!
Yours,
Mr. Snrub
From the Javadoc for SequenceGenerator, emphasis is mine:
Defines a primary key generator that may be referenced by name when a
generator element is specified for the GeneratedValue annotation. A
sequence generator may be specified on the entity class or on the
primary key field or property. The scope of the generator name is
global to the persistence unit (across all generator types).
So you will want to use a unique name for each sequence defined in a persistence unit. On a tangent, your GeneratedValue strategy should be SEQUENCE, as pointed out in a comment above.