UUID does not have hyphens in between - java

Inspired by the suggestion given here - JPA Entity class giving error with 2 #GeneratedValue fields, my question is the OPPOSITE of this - How to generate uuids without dashes
I am using H2 DB and have this in my model:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "useruuid")
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid4")
private UUID userUUID;
And in my controller it goes like this:
#PostConstruct
private void postConstruct() {
AppUser appUser = new AppUser(1l, UUID.randomUUID());
appUserJPARepository.save(appUser);
}
Now when my Spring Boot app starts my H2 DB-Console shows this:
ID USERUUID
1 25b9b7f391d94825b349866fe9a9077c
Question: How do I get hyphens in the DB? So that my uuid in the DB will be - 25b9b7f3-91d9-4825-b349-866fe9a9077c
I fiddled with #GenericGenerator(name = "uuid4", strategy = "uuid4") uuid(1) to uuid5 but got the same result. What is going on here and what I am doing wrong or what should I do to get hyphens in the DB? Any help or related info/links relevant to this will be greatly appreciated.

You can just remove
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid4")
and the code will looks like
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "useruuid")
#GeneratedValue
private UUID userUUID;

Related

Get recently updated results from Database when joining multiple tables using JPA in a Spring application

I am new to Spring and JPA and I am trying to write a job in Spring which runs every 3 hours and retrieve the records from Oracle Database.
I would like to only read the new/updated content from the past 3 hours (ideally from the last job run).
I have seen few examples in https://spring.io/blog/2011/02/10/getting-started-with-spring-data-jpa/ where we can create queries and retrieve the data based on our requirements, but in my current use case, I am not using queries instead using the java classes with the annotations and using Join columns between different tables. There are chances that only one of the sub table is updated or all the tables are updated with new content. I need to get the results if at least one of the table is updated/inserted with new content.
Campus is the main table and retrieves the data from Group and Region, I need to fetch the data if any new data is updated in Campus table or even any group/region is added/modified.
I am using JDK7 as of now.
Is there a way to accomplish the above requirement?
Below are the sample Java classes for reference.
#Entity
#EntityListeners(AuditListener.class)
#Table(name = "TABLE_CAMPUS")
public class Campus implements Auditable {
#Id
#Column(name = "ID)
#SequenceGenerator(name = "SIMPLE_ID", sequenceName = "SIMPLE_ID")
#GeneratedValue(generator = "SIMPLE_ID", strategy = GenerationType.AUTO)
private Long id;
#Column(name = "CAMPUS_NAME")
private String campusName;
#Column(name = "CAMPUS_ID", nullable = false)
private Long campusId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GROUP_ID")
private GroupType groupType;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "REGION_ID")
private Region region;
....
...
}
#Entity
#EntityListeners(AuditListener.class)
#Table(name = "TABLE_GROUP_TYPE")
public class GroupType implements Auditable {
#Id
#Column(name = "GROUP_TYPE_ID")
#SequenceGenerator(name = "GROUP_TYPE_SEQUENCE", sequenceName = "GROUP_TYPE_ID")
#GeneratedValue(generator = "GROUP_TYPE_SEQUENCE", strategy = GenerationType.AUTO)
protected Long id;
#Column(name = "GROUP_TYPE_NAME", nullable = false)
protected String groupTypeName;
....
...
}
#Entity
#EntityListeners(AuditListener.class)
#Table(name = "TABLE_REGION")
public class Region implements Auditable {
#Id
#Column(name = "region_id")
#SequenceGenerator(name = "REGION_ID", sequenceName = "REGION_ID")
#GeneratedValue(generator = "REGION_ID", strategy = GenerationType.AUTO)
private Long id;
#Column(name = "REGION_NAME", nullable = false)
private String name;
...
..
}
Any help is Appreciated.

#GeneratedValue - how do I replace it with my function? (Java 8)

Now the generator goes sequentially with step 1.
I need the ID to generate its own function.
How to substitute its function?
Thank you.
#Entity
#Table(name = "MovementHistory")
public class MovementHistory {
#Id
#SequenceGenerator(name="SEQ_GEN_MH", sequenceName="SEQ_MH", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ_GEN_MH")
private long id;
private long waybillID;
private Date dateEvent;
#ManyToOne(fetch = FetchType.EAGER)
private Status status;
}

Risks of #ID in #MappedSuperclass

Actually, i want to change the entity id from Type Long to the UUID.
All my entites have a MappedSuperclass. To save time, I wanted to add the new solution into the MappedSuperclass object and remove the old solution from the specific entities.
Is this a good practice or is it associated with risks?
old solution
#Entity
public class CustomObject extends DomainObject {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private Long id;
}
new solution
#MappedSuperclass
public class DomainObject {
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Type(type="pg-uuid")
#Column(name = "ID")
private UUID id;
}

How to store uuid in binary form using hibernate JPA 2

I have a question about string uuid in database in binary form through hibernate persistence (JPA2). I'm using now this code:
private UUID id;
#Id
#Type(type="uuid-char")
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid")
#Column(length = 32, unique = true, nullable = false)
public final UUID getId() {
return id;
}
This work fine, but I must store it in binary form. Don't ask me why, but I must.
The type for binary UUID is uuid-binary. You must have Hibernate 3.6 for this to work.
For many more details and pitfalls, see the answers to this question.

Using Hibernate UUIDGenerator via annotations

I'm using my uuid as following:
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
#Column(name = "uuid", unique = true)
private String uuid;
but I'm getting a smart Hibernate warning:
Using
org.hibernate.id.UUIDHexGenerator
which does not generate IETF RFC 4122
compliant UUID values; consider using
org.hibernate.id.UUIDGenerator instead
So I want to switch to org.hibernate.id.UUIDGenerator, now my question is how should I tell it to Hibernate's generator. I saw some guy used it as a "hibernate-uuid" - so this is what I've tried, but with negative result:
#Id
#GeneratedValue(generator = "hibernate-uuid")
#GenericGenerator(name = "hibernate-uuid", strategy = "hibernate-uuid")
#Column(name = "uuid", unique = true)
private String uuid;
It should be uuid2:
...
#GenericGenerator(name = "uuid", strategy = "uuid2")
...
See 5.1.2.2.1. Various additional generators.
HibernateDoc says you can use following:
#Id
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name = "uuid", unique = true)
private String uuid;
I hope you are using Hibernate 3.5.
As #natan pointed out in a comment, if you are using Hibernate 5 the below code is sufficient:
#Id
#GeneratedValue
private java.util.UUID id;
Define the id column with the type of BINARY(16) in MySQL or it's equivalent in other SQL implementations.
Try...
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#Column(name = "uuid", columnDefinition = "BINARY(16)")
public UUID getId()
{
return id;
}
public void setId(UUID i)
{
id = i;
}
Note the "uuid2" as opposed to "uuid".
This will use UUID v4 and the auto generated uuid will be stored in the column as usual varchar(36):
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "uuid2")
#Column(length = 36)
private String uuid;
This should have some performance impact:
consumed size is more than BINARY(16)
after hydration the java.lang.String instance consumes more memory than java.util.UUID: 112 bytes for UUID as string versus 32 bytes (i.e. two longs + obj header) for UUID.
But it's much more easier to work with string'ed UUID - easier to write queries and you can see the contents of the table.
Tested on Hibernate 5.3
Unknown Id.generator: hibernate-uuid
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
#Column(name = "id", unique = true)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
With current 5.4.2 Hibernate version,
if you want a Human-Readable varchar(36) field in the database table,
but also a Serializable UUID data type in your Java Class,
you can use #Type(type = "uuid-char") at the same time you declare your field member with java.util.UUID type.
Note that #Column(length = 36) is important to reduce from 255 to 36 the field length in MySQL.
Note that with PostgreSQL you should use #Type(type = "pg-uuid") instead.
import org.hibernate.annotations.Type
import java.util.UUID
import javax.persistence.Column
import javax.persistence.GeneratedValue
import javax.persistence.Id
#Id #GeneratedValue
#Type(type = "uuid-char") #Column(length = 36)
private UUID id;
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
#Column(name = "UUID_ID")
public String getId(){
return id;
}
This is the proper way to use annotation for uuid generators in Hibernate 5.0.11.FINAL.
Note: IT is deprecated.

Categories