Postgresql Spring Data #GeneratedValue without #Id return null value - spring-boot

im working in spring boot project i want to map a property with serial (using my sequence) column in my table and this column is not the ID.
i found this solution :
#Column(name = "DEMANDE_NUMBER", insertable = false, updatable = false, columnDefinition = "serial")
private Integer demandeNumber;
(because #GeneratedValue persist null and doesn't use the sequence)
this solution works fine and the field is persisted in my DB and the value uses the sequence but when i get my object after saving using my repository the demandeNumber is null
Demande savedDemande= demandeRepository.save(demandeToSave);
//demandeObj .getDemandeNumber() return null
any suggestion to resolve this issue please ?
Thanks.

according to this answer How to use a sequence generator for a non ID field?
i added the following annotation on my property
#Generated(GenerationTime.INSERT)
#Column(name = "column_name", columnDefinition = "serial", updatable = false)
you should import the package from hibernate and not javax.persistence.
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
i hope this can help other people in the future. note this solution is for spring data with postgresql.

Related

Race Condition in Postgres SQL using Spring data JpaRepository

I am facing a wierd issue in my implementation where I am persisitng data to a PostgresSQL DB using Spring data JpaRepository
In my Entity class I have the below columns:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private int id;
#Column(name = "field1", nullable = false, length = 16)
private String field1;
#Column(name = "field2", nullable = false, length = 16)
private String field2;
#Column(name = "field3", nullable = false, length = 16)
private String field3;
I initially avoided declaring the fields above as composite since there were many fields to be dealt with as composite keys. I thought the java code check would do the trick in all scenarios
So basically, I have to maintain the uniqueness of each row based on field1,field2 and field3. That was the basic requirement for which I had checks in my java code that if any entry exists in the DB for the combination of field1,field2 and field3 then I used to throw java exceptions
No two rows can have these values repeating. All was good until the application was tested under some errorneous business scenarios which would never happen in production but got run by mistake
Whats happening now is that if 2 requests are triggered at the exact same instance with the exact same 3 fields above (through a script) then they both enter into the Database since both get the entry check as false
Would declaring all of them as one composite key resolve the situation?
You should define the unique constraint in your database in addition of JPA constraint.
#Entity
#Table(uniqueConstraints={
#UniqueConstraint(columnNames = {"field1", "field2", "field3"})
})
public class MyEntity {
...
}

Manage String id sequence in spring boot entity

I'm working on oracle database to manage a JPA entity with a String Primary key.
I cannot modify the type on the PK to a Long or int in the database, so i want to know how to configure the pk sequence in my JPA entity,
i've tried this :
#Id
#SequenceGenerator(name="SEQ_ID", sequenceName = "SEQ_ID" )
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_ID")
#Column(name="SEQ_ID",unique=true, nullable = false,updatable = false)
private String id;
but when persisting a new entity i got the error : Unknown integral data type for ids : java.lang.String
someone can help me please ?
Try removing #GeneratedValue and #SequenceGenerator
Also, a remark, #Id will automatically set unique=true, nullable = false,updatable = false so you can remove them from #Column.
Otherwise, you can check this article for more details about creating a custom string generator https://vladmihalcea.com/how-to-implement-a-custom-string-based-sequence-identifier-generator-with-hibernate/

oracle with spring boot not fetching by primary key

I have written a spring boot app with oracle db.
Below is my entiry class.
#Entity
public class SystemTypeLookup{
#Id
#GeneratedValue(generator = "UUID")
#GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
#Type(type = "uuid-char")
#Column(name = "ID", updatable = false, nullable = false)
protected UUID id;
#Column(name = "CODE")
private String code;
}
And in passing my own UUID as primary key value.
In oracle db ID is considered as RAW and the UUID stored in oracle is differently.
There is no - separation in oracle and all the UUID chars are in upper case.
When i try to find the entity using primary key it is not fetching the row with id. I'm always getting null.
#Resource(name = "coreRepository")
private ErpEntityRepository coreRepositoryBase;
SystemTypeLookup systemTypeLookup = coreRepositoryBase.findOne("WHERE o.id='"+id+"'", SystemTypeLookup.class);
when is pass 76c03cd9-3d96-40c5-8df9-aad8f2369453 as id value then the oracle will insert the id without '-' and all chars will be in upper case.
So how to solve this issue?
First of all you should use parameters in your query and second make sure that the id you are passing is of type UUID and not String.

Switch between databases in spring/ hibernate

In my project I use Spring and hibernate. I use MySql and use auto increment for Ids. But now I need to support multiple database types. (separate installations). Say, MySql, Oracle (11g), Postgresql, etc.
My current idea is to use uuid for primary keys since I can switch to any database without much worrying about database layer. But since I have used Integer for auto_increment I have to modify my code base.
Is there a way to preserve Integer id? or shall I proceed with uuid ?
Current implementation
#Id
#GeneratedValue
#Column(name = "id", nullable = false, updatable = false)
private Integer id;
Or this, (or any other solution)
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
#Column
#Id
private String id;
I found a way to do this.
Idea is to add annotation configuration and override it using xml.
XML metadata may be used as an alternative to these annotations, or to override or augment annotations
Here is a good tutorial for this,
https://vladmihalcea.com/how-to-replace-the-table-identifier-generator-with-either-sequence-or-identity-in-a-portable-way/

Unique Key Constraint in Spring Data Jpa

How to make a field unique in pojo using spring data jpa?I know how to do that using jpa
For reference: multi column constraint with jpa
If there is a way, is it possible to use with spring boot?
Use the #UniqueConstraint annotation to specify that a unique constraint is to be included in the generated DDL for a primary or secondary table.
Alternately, to ensure a field value is unique you can write
#Column(unique=true)
String myField;
With Spring Data JPA you are using JPA, so you specify the unique constraint using JPA. Nothing special from Spring Boot or Spring Data on that front.
Um exemplo em Kotlin:
Entity
#Table(name = "TBL_XXX",
uniqueConstraints = [
UniqueConstraint(name = "sessionid_uindex", columnNames = ["sessionId"])
]
)
data class XxxReturn(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "XXX_ID")
var id: Long? = null,
var sessionId: String,
var msg: String
)
If you have a single column in the table that has UNIQUE KEY constraint then you can simply add the attribute unique=true in the annotation #Column
CODE SNIPPET:
#Column(name = "unique_key_field", nullable = false, unique = true)
String uniqueKeyFied;
In case if you have multiple Unique key constraints in the table then you have to simply follow with the JPA annotations as the spring-boot-data-starter does not provide any special annotations for the table constraints(KEY/UNIQUEKEY).
CODE SNIPPET:
#Entity
#Table(name = "table_name", uniqueConstraints={
#UniqueConstraint( name = "idx_col1_col2", columnNames ={"col1","col2"})
})

Resources