deprecated SequenceHiLoGenerator sequence-based id generator; use SequenceStyleGenerator instead - java

my application is logging
org.hibernate.orm.deprecation : HHH90000014: Found use of
deprecated [org.hibernate.id.SequenceHiLoGenerator] sequence-based id
generator; use org.hibernate.id.enhanced.SequenceStyleGenerator
instead. See Hibernate Domain Model Mapping Guide for details.
There is a similar question about this here that fix the problem, but my question is if it's possible replace the Sequence generator org.hibernate.id.SequenceHiLoGenerator
to org.hibernate.id.enhanced.SequenceStyleGenerator without go throught every single domain class annotations writing a custom #GenericGenerator? Something like a property maybe...
My code has something like this:
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="seq_name")
#SequenceGenerator(name="seq_name", sequenceName="hibernate_sequence")
private Long id;
Thank you.

You should be able to set hibernate.id.new_generator_mappings to true, which is the default in Hibernate 5, and that should disable the legacy behavior and automatically selecting the enhanced generator.

Related

Oracle JPA GenerationType.AUTO with generator asks for "hibernate_sequence"

I'm trying to use a defined sequence generation in Oracle JPA, along with GenerationType.AUTO like this:
#Id
#SequenceGenerator(name = "MY_GEN_NAME", sequenceName = "MY_SQ_NAME")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "MY_GEN_NAME")
#Column(name = "ID", nullable = false)
private Long id;
After running the hibernate validation it throws an error:
Schema validation: missing sequence [hibernate_sequence]
I guess, it is ignoring my MY_GEN_NAME and trying to use that global sequence for id generation.
When I switch to GenerationType.SEQUENCE, it uses SequenceHiLoGenerator and it works fine.
Why is that happening, and is it possible to make the GenerationType.AUTO work with given sequence for Oracle (possibility to switch to other db)?
AUTO says to the JPA provider, "choose what you want", and it will not use the "generator" attribute in that case.
If you want to use a SEQUENCE then set the strategy to SEQUENCE! That way it will use the sequence definition you have defined
Though hibernate-sequence-on-oracle-generatedvaluestrategy-generationtype-auto suggests that this will work, it appears that it is broken for some versions of Hibernate, see HHH-10656.
Edit: Broken in 5.2.0, unbroken in 5.2.8.

How to replace deprecated MultipleHiLoPerTableGenerator with TableGenerator in Hibernate

I use hibernate in an application with spring boot 1.4.0.RELEASE.
The Entity for the index looks something along the lines of:
#Entity(name = "SearchableTariffItem")
#Indexed
public class SearchableTariffItem {
public static final String ZIFFER_ANALYZER_NAME = "ZIFFER_ANALYZER";
#GeneratedValue(strategy = GenerationType.TABLE)
#Id
private Long id;
...
}
I now get the following warning when I save the entity for the first time:
2016-08-26 15:08:32.501 WARN 8476 — [apr-8080-exec-6] org.hibernate.orm.deprecation : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead. See Hibernate Domain Model Mapping Guide for details.
Unfortunately I don't know where I can configure my application (preferably in a the application.yml) to use the TableGenerator class.
I use the following dependency:
Hibernate core 5.0.9.Final
Hibernate search ORM 5.5.1.Final
Lucene 5.3.1
The property that controls this behaviour in Hibernate is hibernate.id.new_generator_mappings, which defaults to true for Hibernate 5 -> which means the new TableGenerator will be used instead of the deprecated MultipleHiLoPerTableGenerator .
Spring Boot however defaults this property to false, which means the old generator will be used, unless you explicitly tell it you want the new one.
You need to set the property spring.jpa.hibernate.use-new-id-generator-mappings to true to get the TableGenerator.
See https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#generator-mappings

Spring Boot hibernate using different naming convention to session save

Similar to this problem:
ORA-00904: : invalid identifier Issue with Hibernate Dependent objects program
I'm trying to do batch inserts using hibernate. Whenever I try to do a session.save or session.saveOrUpdate, hibernate complains that I have an invalid identifier
Stack output
2015-11-20 14:17:37 ERROR : ORA-00904: "USERATTRID": invalid identifier
Entity
public class Attribute {
#Id
#GenericGenerator(name = "increment", strategy = "increment")
#GeneratedValue(generator = "increment", strategy = GenerationType.SEQUENCE)
private int USERAttrID;
private long userNumber;
private String attribute;
private String value;
private String description;
private LocalDateTime updatedDate;
private LocalDateTime createdDate;
The database looks like this after hibernate applies its improved naming convention
USER_ATTRID
ATTRIBUTE
USER_NUMBER
DESCRIPTION
VALUE
CREATED_DATE
UPDATED_DATE
If I use repository.save then the code works fine. The crud repository seems to know how to map my entity to the database, but hibernate's session does not.
I see a few solutions here:
1. Use hibernate's default default naming strategy. Tables get named things like USERATTRID. I'm not sure what implications this has other than making columns harder to read.
2. Combine hibernate with crudrepository using the tutorial here
http://frightanic.com/software-development/jpa-batch-inserts/
3. Figure out how to get hibernate's session.save to use the improvedNamingConvention mapper. Can anyone help me with this or provide me another suggestion?
4. I guess I can also manually map the columns :/. Ugh this is messy, you now have to manually do all the conversions on dates :/
It would be good to know how you are actually getting the session?The most likely cause that comes to mind is that when you using the hibernate session it is actually not built using the same configuration that was used to build the entity manager that CrudRepository uses underneath.
Ends up being more trouble than it's worth as you stop using hibernate jpa's defaults and all the things spring-data provides you out of the box
Stupid. The tutorial doesn't even use crudRepository
Same as 1
Same as 1
Instead I'm banging my head against a wall trying to get a simple batch process to insert

Auto generate unique random string in Spring MVC + Hibernate

Background
I'm writing a project using Spring MVC (Framework v4.0.6.RELEASE, JPA v1.6.2.RELEASE) and Hibernate (Core v4.3.6.FINAL, JPA API v2.1). In my project, there are entities called 'Project'. Each of these projects have their unique, auto-generated IDs as primary keys. This ID is generated by the following code:
#Id
#Column(name = "project_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long projectId;
This code works as expected and automatically creates unique IDs.
Problem
Each of these projects are supposed to have a random, unique1 'secret' String, just like those assigned by API providers like Facebook, Twitter, etc. So, to achieve this, I tried using the following code, as per the Hibernate docs:
#Column(name = "project_secret", nullable = false, unique = true)
#GenericGenerator(name = "uuid-gen", strategy = "uuid")
#GeneratedValue(generator = "uuid-gen")
private String projectSecret;
However, whenever I try to create a new project entity, I'm greeted by a org.springframework.dao.DataIntegrityViolationException with root cause:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Column 'project_secret' cannot be null
This should be auto-generated by Hibernate on creation, must be random and unique1. A 128-bit UUID is enough for me (32 characters w/out dashes) and I read that Hibernate has a UUID generator, so that's what I was aiming to use.
Further Info
After searching for hours, I'm no closer to solving it the way I want to do it. I found one possible solution, which is to include:
#PrePersist
private void generateSecret(){
this.setProjectSecret(UUID.randomUUID().toString());
}
in the Project entity class. When this method is inserted (and #GenericGenerator & #GeneratedValue tags removed), the project secret is correctly generated and inserted; system works as expected; no exceptions are thrown. However, (I believe) this can't ensure uniqueness2 and just causes an exception when a duplicate secret is inserted. I want to ensure uniqueness and preferably want to solve this with built-in Hibernate generators.
(Notes)
I actually am not sure if uniqueness should be enforced. I suppose having every secret unique can (theoretically) create an additional layer of security, which takes me to:
I realise that the probability of UUID collision is very very low, so UUID generation ensures that uniqueness in a probabilistic sense but can (or should) I be really sure of it?
I had an issue like this before and I realised after a while that it was my database table that was causing the issue. This might be the same problem you are having...
For your project_id ensure you use the following when you are creating that column in the database
GENERATED ALWAYS AS IDENTITY
I hope this is the same issue and that this will be of help to you. Also would recommend using uuid2 as your strategy.
see here... http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html#d0e5294
Edit
After realising that project_secret is not the #id field then the answer is that hibernate does not support generated values on any column except for the #id field.
See here for more details : Hibernate JPA Sequence (non-Id)

Why Hibernates ignores the name attribute of the #Column annotation?

Using Hibernate 3.3.1 and Hibernate Annotations 3.4, the database is DB2/400 V6R1, running that on WebSphere 7.0.0.9
I have the following class
#Entity
public class Ciinvhd implements Serializable {
#Id
private String ihinse;
#Id
#Column(name="IHINV#")
private BigDecimal ihinv;
....
}
For reasons I can't figure, Hibernate ignores the specified column name and uses 'ihinv' to generate the SQL:
select
ciinvhd0_.ihinse as ihinse13_,
ciinvhd0_.ihinv as ihinv13_,
...
Which of course gives me the following error:
Column IHINV not in table CIINVHD
Edit: I switched the log level of hibernate to DEBUG, and I see that it does not process the column annotation for that field. Tried several random things it just doesn't work.
Did anyone had this problem before? I have other entities that are very alike in the way that they are using # in their database field names and that are part of the PK and I don't have this problem with them.
You could try some kind of quoting:
For example:
#Column(name="`IHINV#`")
or
#Column(name="'IHINV#'")
Another option would be to dig in to source code Hibernate dialect for DB2 and see if it contains anything helpful.
Of course, the easiest way would be to remove the hash from column name if possible.
I suspect that the problem is the hash in the column name. A similar question on the hibernate forums suggests that backticks can be useful here.

Categories

Resources