JPA + Hibernate, Error : com.microsoft.sqlserver.jdbc.SQLServerException: The column name value is not valid - spring

I'm trying to use JPA + Hibernate to call a Store procedure with #Query annnotation
#Query(value = "exec dbo.getUserById :Id", nativeQuery = true)
User findUserById(#Param("Id) Long id);
and map the result to the follow entity
#Entity
#Table(name = "users_contact")
public class User{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Integer id;
private String userName;
private String value;
}
Store procedure only return 'id' and 'userName' columns, so when i call findUserById method Spring throws the follow error
Error : com.microsoft.sqlserver.jdbc.SQLServerException: The column name 'value' is not valid
I guess its because Hibernate try to find 'value' property and map to 'value' property in the entity but for this query i dont need value property.
Its a requirement in the proyect that i only use store procedures to access to the database, so i can't use SQL native queries.
Is there any configuration available to specified ignore this property only for the call to this store procedure?

You have:
private String name;
Try changing "name" to say - "somename". This is causing the issue if you look at the exception. "name" is a reserved keyword. For simplicity if your entity is say TheUser, then use something like - username instead of name. I hope you got the idea !

Related

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.

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/

#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.

Fetch child entities when finding by a normal field in Spring Data JPA

I am using Spring Data JpaRepository to find List of entities matching a particular field. Consider the following code snippet:
Entity:
#Entity
#Table(name = "master")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Master implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
#Column(name = "id", nullable = false)
private Long Id;
#NotNull
#Column(name = "user_id", nullable = false)
private String userId;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="id", referencedColumnName="id", insertable=false, updatable=false)
private Details Details;
Spring Data Custom JpaRepository:
public interface MasterRepository extends JpaRepository<Master,Long> {
List<Master> findMasterByUserId(String userId);
}
When i am using findBookingMasterByUserId repository method to find all records with specific user id, I am getting the List of Master entity but I am not getting the Details entity that has id as foreign key in it.
However, I get all the dependent entities when I use out of the box findAll method of JpaRepository but with custom findMasterByUserId repository method, child entities are not being fetched eagerly.
Any type of help would be highly appreciated. Thanks!
You can use #EntityGraph in your repo to eagerly get associated data:
#EntityGraph(attributePaths = {"details"})
List<Master> findBookingMasterByUserId(String userId);
P.S. Don't forget to change 'Details' field to details;
Your entity name is "Master" not "booking_master".
Change your method to:
List<Master> findByUserId(String userId);
Refer to below spring docs for more information on query creation mechanism for JPA.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/
Alternatively,
#Query("SELECT m FROM Master m WHERE m.userId = :userId")
List<Master> findByUserId(#Param("userId") String userId);
The query generation from the method name is a query generation strategy where the invoked query is derived from the name of the query method.
We can create query methods that use this strategy by following these rules:
The name of our query method must start with one of the following
prefixes: find…By, read…By, query…By, count…By, and get…By.
If we want to limit the number of returned query results, we can add
the First or the Top keyword before the first By word. If we want to
get more than one result, we have to append the optional numeric
value to the First and the Top keywords. For example, findTopBy,
findTop1By, findFirstBy, and findFirst1By all return the first entity
that matches with the specified search criteria.
If we want to select unique results, we have to add the Distinct
keyword before the first By word. For example, findTitleDistinctBy or
findDistinctTitleBy means that we want to select all unique titles
that are found from the database.
We must add the search criteria of our query method after the first
By word. We can specify the search criteria by combining property
expressions with the supported keywords.
If our query method specifies x search conditions, we must add x
method parameters to it. In other words, the number of method
parameters must be equal than the number of search conditions. Also,
the method parameters must be given in the same order than the search
conditions.

Spring MVC - loading data

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.

Resources