Issues updating record with Hibernate and Spring - spring

I am having one-to-many relationship tables. When I insert records, the program inserts new records without any problem, but when I try to update the record by using saveOrUpdate(), the program does not work as my expectation. Only parent table (e.g., student) record is updated and new records inserted in the child table (e.g., studentaddress). As in the parent table, I need an update in child table too.
How to achieve this? Please help me. Following is the Hibernate tool-generated code:
Student Table
#OneToMany(fetch = FetchType.LAZY, mappedBy = "student",cascade=CascadeType.ALL)
Studentaddress Table
#ManyToOne(fetch = FetchType.LAZY) #JoinColumn(name = "student_id", nullable = false)
I have searched a lot but could not get any site relating to update but I have seen some sites for one table update. In my case, I want to update two tables.

try to add to student this
#org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)

Related

Spring boot hibernate always drop and create index on server startup

Spring boot hibernate always drop and create ALL the indexs on server startup
spring.jpa.hibernate.ddl-auto = update
Hibernate: alter table product_category_1 drop index UKkqfeccp86g07ipixmg25dnfia
Hibernate: alter table product_category_1 add constraint
UKkqfeccp86g07ipixmg25dnfia unique (org_id, pr_ty_id, name)
Hibernate: alter table product_category_2 drop index UKqa7n4ip0gfa4qpg034ba7bkob
Hibernate: alter table product_category_2 add constraint UKqa7n4ip0gfa4qpg034ba7bkob unique (org_id, pr_ca1_id, name)
If your column type is a longtext, the index is not created so hibernate tries to recreate it.
I was experiencing the same thing, where starting my application resulted in my unique constraints being dropped and re-added:
Hibernate: alter table category drop constraint if exists UK_CATEGORY_PARENT_NAME
Hibernate: alter table category add constraint UK_CATEGORY_PARENT_NAME unique (parent_id, name)
After much internet digging and debugging, I found simply adding the following to my application properties no longer caused the constraints to be dropped:
spring.jpa.properties.hibernate.schema_update.unique_constraint_strategy=RECREATE_QUIETLY
As i observe that few of the unique key drop and create again and again with the property
spring.jpa.hibernate.ddl-auto = update
You have to change the uniqueConstraints write inside the #Table annotation and put the uniqness check at column level
Execute the drop and create unique index again and again every time you restart the project
#Table(name = "XXXX",
uniqueConstraints = {#UniqueConstraint(columnNames = { "tempUserId"}) },
)
Resolve by adding the unique=true and column level
#Column(unique = true)
private Long tempUserId;
And delete uniqueConstraints from the #Table annotation
This will resolve the problem

Cassandra + SpringBoot: Configure Table to automatically add INSERT timestamp

Small question regarding Cassandra, with the context of a SpringBoot application please.
I am interested in adding onto the table the timestamp of when a row gets inserted onto the table.
Therefore, when creating the table, I do this:
create table mytable (someprimarykey text PRIMARY KEY, timestamp long, someotherfield text);
I can see a column timestamp, happy.
Then, the web application:
#Table
public class MyTable {
#PrimaryKey
private final String somePrimaryKey;
private final long timestamp;
private final String someOtherField;
//constructor + getters + setters
And when I insert, I will do the usual:
MyTable myTable = new MyTable(somePK, System.currentTimeMillis(), "foo");
myTableRepository.save(myTable);
This works fine, I can see in the table my record, with the time of the insert, happy.
Problem:
Now, for the hundreds of POJOs I am interested to insert into Cassandra, all of them are carrying this timestamp long field. Somehow, on the web application layer, I am dealing with a database concept, the timestamp of the write.
Question:
May I ask if it is possible to delegate this back to the database? Some kind of:
create table mytable (someprimarykey text PRIMARY KEY, hey-cassandra-please-automatically-add-the-time-when-this-row-is-written long, someotherfield text);
or
create table mytable (someprimarykey text PRIMARY KEY, someotherfield text WITH default timestamp-insert-time-column);
And the web app can have the abstraction creating and inserting POJOs without carrying this timestamp field?
Thank you
It isn't necessary to store the insert time of each row separately since Cassandra already stores this for all writes in the metadata.
There is a built-in CQL function WRITETIME() which returns the date/time (encoded in microseconds) when a column was written to the database.
In your case, you can query your table with:
SELECT WRITETIME(someotherfield) FROM mytable WHERE someprimarykey = ?
For details, see the CQL doc on retrieving the write time. Cheers!

#OneToMany Column not showing?

I am new to Hibernate and curious, why my column is not showing.
So I have following code (in kotlin):
#Entity
class Project (
var guid: String = "",
#OneToMany(mappedBy = "project", cascade = [CascadeType.ALL])
var tickets: List<Ticket?>,
var current: Date
){
#Id #GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0
}
and the other entity:
#Entity
class Ticket (
var guid: String = "",
#ManyToOne
#JoinColumn(name="project_id")
var project: Project?,
var current: Date
){
#Id #GeneratedValue(strategy = GenerationType.AUTO)
var id: Long = 0
}
In my database, the table "ticket" has a column project_id, with null values.
BUT my other table "Project" has no column for the list of Tickets. What went wrong? Every help will be appreciated, please dont forget to explain.
Thank you!
The reason your Project table has no column for the list of tickets, is that relational databases are designed to have one value per cell. You cannot store a list or array of something in a table. The solution for this is to create another table (let's call it the child table) that references this table (the parent table). Each row in the child table will be one entry of that list, and stores a reference to the parent list. So in a way, the relationship has been inverted: instead of storing the tickets in the Project table, a reference to the Project table is stored in the Ticket table.
In your case, you're indicating that the project_id should be used as a reference, since you're mentioning it in the #JoinColumn. However, there is no such property in the Project table, so you should add it. Hibernate is expecting that this is the column to link the two tables.
Also: don't forget to create a foreign key constraint to the parent table on the column that you're using in the Ticket table either.

Hibernate insert with id generation on insert trigger with sequence

Here my problem, I have a sequence in my oracle database and a trigger on insert to fetch the next value from the sequence and put it as id. With a tool like sql developer, it works perfectly.
My id is defined at this
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MY_SEQUENCE")
#SequenceGenerator(sequenceName = "MY_SEQUENCE", allocationSize = 1, name = "MY_SEQUENCE")
private BigInteger jobId;
The problem is hibernate firstly read the next value of the sequence, set it as the id and then persist it. Then my database update my id with the next value of the sequence but that new id isn't "updated" in my code after my .save(entity).
I read that I should use the GenerationType.IDENTITY but I would like to do batch inserts and I also read that with IDENTITY the batch inserts is not possible.
If possible, I would like to keep my trigger so like that hibernate doesn't have to call the database each time I insert and be able to do batch inserts.
Edit: I'll probably need to insert near a million of rows

Spring Data/JPA PostgreSQL SequenceGenerator and duplicate primary keys on concurrent access to the same database

In my Spring Data/JPA project I use ProstgreSQL database.
I use a following mapping for my JPA entity PK on cards table:
#Id
#SequenceGenerator(name = "cards_id_seq", sequenceName = "cards_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.AUTO, generator = "cards_id_seq")
private Long id;
Everything works fine until some other applications or persons do not insert manually new records into this table. Once it happens my application fails with the following error:
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "cards_pkey"
Detail: Key (id)=(42) already exists.
when tries to insert records because of out of sync between PostgreSQL sequence object and actual PK IDs in the database.
What am I doing wrong and how to solve this situation in order to assign the correct IDs to new records inserted via my application ?

Resources