Spring MVC - loading data - spring

I have filled database and one entity which uses 2 tables like this:
#Entity
#Table(name="Product")
#SecondaryTable(name="B")
public class Product {
#Id
#GeneratedValue
private int idProduct;
#Column(name="name")
private String name;
#Column(table="B",name="aaaa")
private String aaa;
#Column(table="B",name="bbbb")
private String bbbb;
When I'm loading data from database table B is cleared, why?
I tried to change value in hibernate.hbm2ddl.auto from "create-drop" to "update" but I have an error like this:
"Can not set int field com.packt.webstore.domain.Product.bbbb to null value".
I need to load and write data to database so which value shoud I set and how to fix this error?
EDIT: When I set #Column(name="bbb", nullable=true) is the same error.

Related

Document field as primary key not working

I have a "document" field that needs to be a primary key and must be unique, but every time I do a POST with the same document it updates the document and doesn't send a BAD_REQUEST
My entity:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Table(uniqueConstraints={#UniqueConstraint(columnNames={"document"})})
public class Cliente {
#Id
#Column(unique=true, updatable = false)
#NotBlank #NotNull
private String document;
#NotBlank
private String name;
#NotNull
private LocalDateTime date;
}
When I try to make a new POST with the same document it just updates what is saved in the database.
"Hibernate: update client set date=?, name=? where document=?"
The problem is that Spring Data JPA, when you call Repository#save, assumes that you want to update an existing entity when the passed in entity object has the id attribute set. You will have to inject a EntityManager in your code and instead call EntityManager#persist if you want to make sure that Hibernate tries to do an insert, in which case you'd get a constraint violation exception, just as you expect.

Spring Data + View with Union return duplicate rows

i'm using Spring Boot 2.4.2 and Data module for JPA implementation.
Now, i'm using an Oracle View, mapped by this JPA Entity:
#Entity
#Immutable
#Table(name = "ORDER_EXPORT_V")
#ToString
#Data
#NoArgsConstructor
#EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class OrderExportView implements Serializable {
private static final long serialVersionUID = -4417678438840201704L;
#Id
#Column(name = "ID", nullable = false)
#EqualsAndHashCode.Include
private Long id;
....
The view uses an UNION which allows me to obtain two different attributes of the same parent entity, so for one same parent entity (A) with this UNION I get the attribute B in row 1 and attribute C in row 2: this means that the rows will be different from each other.
If I run the query with an Oracle client, I get the result set I expect: same parent entity with 2 different rows containing the different attributes.
Now the issue: when I run the query with Spring Data (JPA), I get the wrong result set: two lines but duplicate.
In debug, I check the query that perform Spring Data and it's correct; if I run the same query, the result set is correct, but from Java/Spring Data not. Why??
Thanks for your support!
I got it! I was wrong in the ID field.
The two rows have the same parent id, which is not good for JPA, which instead expects a unique value for each line.
So, now I introduced a UUID field into the view:
sys_guid() AS uuid
and in JPA Entity:
#Id
#Column(name = "UUID", nullable = false)
#EqualsAndHashCode.Include
private UUID uuid;
#Column(name = "ID")
private Long id;
and now everything works fine, as the new field has a unique value for each row.

Advantage of assigning the returned savedEntity in Spring Data

I see in most of the coders save data(using spring data) as:
savedEntity = repo.save(savedEntity);
Long id = savedEntity.getId();
I am confused about why most of them assign back the returned value to the saved Entity while the following code also works exact(I have tested myself):
repo.save(savedEntity);
Long id = savedEntity.getId();
Did I miss some benefit of assigning back?
for example, let the entity be:
#Entity
public class SavedEntity {
#Id
private int id;
private String name;
//getter, setters, all arg-constructor, and no-arg constructor
}
Consider the object of SavedEntity is
SavedEntity entity = new SavedEntity(1,"abcd");
now for your first question,
SavedUser entity1 = repo.save(entity);
Long id = entity1.getId();
this entity1 object is the return object getting from the database, which means the above entity is saved in the database succesfully.
for the Second Question,
repo.save(entity);
Long id = entity.getId();//which you got it from SavedEntity entity = new SavedEntity(1,"abcd");
here the value of id is the integer you mentioned in place of id(the raw value).
Most of the time the id (primary key) is generated automatically while storing the entity to the database using strategies like AUTO, Sequence etc. So as to fetch those id's or autogenerated primary key values we assign back the saved entity.
For example:
#Entity
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
}
In this case you'll not pass the id externally but it will create a value for it automatically while storing the data to DB.

#Id annotation Causing duplication in list

I am using Hibernate for calling Stored procedure
Response returned by Stored procedure
receiverId fcmId source
1234 xyz android
45678 abc web
9876 fgh android
1234 ygh ios
Hibernet #EntityClass
#Entity
public class receieverDetails {
#Id
#Column(name="receiverId")
private String receiverUserId;
#Column(name="fcmId")
private String fcmIds;
private String source;
}
I am getting List of receiverDetails from database
if List contain duplicate receiverId as show is above response, 1st one is replacing the 4th details
Code for Binding
ProcedureCall procedureCall1 =
session.createStoredProcedureCall(Strings.StoredProcedureNames.GET_RECEIVER_INFO_OF_SPONSORED_MESSAGE,receieverDetails.class);
Output output1 = procedureCall1.getOutputs().getCurrent();
if(output1.isResultSet()) {
List<receieverDetails> receievers = ((ResultSetOutput) output1).getResultList();
}
i think this is causing by #Id annotation in the entity class, Because it is happening with same receiverIds only
Kindly Help me on this
In your code by providing the #Id annotation to the column receiverId, you are telling the code that this field is to be used as the primary key for the table.So, when fetching the data the issue occurs as there are duplicate values in the table for this column. Either you need to set the primary key correctly, or make this column as primary key in table and correct your code.
If you are using the same entity class to persist data and make column receiverId primary key then try using the below :
#Entity
public class receieverDetails {
#Id
#Column(name="receiverId",unique=true,nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private String receiverUserId;
#Column(name="fcmId")
private String fcmIds;
private String source;
}
unique=true in #Column is a shortcut for #UniqueConstraint(columnNames = {"receiverId"} and other particular constraints.The #GeneratedValue annotation is to configure the way of increment of the specified column(field).
or if the primary key of the table is some other field in table please correct the code to reflect the same.

Spring Data Redis -- How to have alias name for the variable in spring data redis?

In the below code if I want to store the id as student_id and name as student_name in redis database and I don't want to change the name of variable in my java code. Is there any way out to provide alias name for the variable as we do in spring data jpa we specify the name of the column in #Column annotation. Please help me out if anyone has the solution for the same.
#RedisHash("Student")
public class Student implements Serializable
{
#Id
private Long id;
private String name;
private float marksObtained;
private String schoolName;
}

Resources