spring data jpa can't use native sql to update data - spring

I try insert,delte,update method . My code:
package com.example.tx.repository;
import com.example.tx.entity.Blog;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
public interface BlogRepository extends CrudRepository<Blog,Long> {
#Transactional
#Modifying
#Query(value = "insert into blog (title,content) value(:title,:content)",nativeQuery = true)
void saveBlog(#Param("title") String title,#Param("content") String content);
#Transactional
#Modifying
#Query(value = "update blog set content = :content where id = :id" ,nativeQuery = true)
void update(#Param("id") Long id,#Param("content") String content);
#Transactional
#Modifying
#Query(value = "delete from blog where id = :id",nativeQuery = true)
void deleteWithId(#Param("id") Long id );
}
idea log
2020-04-29 14:50:26,110 restartedMain DEBUG AsyncLogger.ThreadNameStrategy=UNCACHED (user specified null, default is UNCACHED)
2020-04-29 14:50:26,110 restartedMain DEBUG org.apache.logging.log4j.core.util.SystemClock does not support precise timestamps.
14:50:26.112 [restartedMain] DEBUG com.example.tx.TxApplication - Running with Spring Boot v2.2.6.RELEASE, Spring v5.2.5.RELEASE
14:50:26.112 [restartedMain] INFO com.example.tx.TxApplication - No active profile set, falling back to default profiles: default
14:50:30.050 [restartedMain] INFO com.example.tx.TxApplication - Started TxApplication in 4.269 seconds (JVM running for 6.579)
Hibernate: update blog set content = ? where id = ?
only the update method can't work , the data can't change, how to resolve it ?

you've to put below properties in #Modifying annotation like blow,
#Transactional
#Modifying(clearAutomatically = true,flushAutomatically = true)
#Query(value = "update blog set content = :content where id = :id" ,nativeQuery = true)
void update(#Param("id") Long id,#Param("content") String content);

Related

SpringData JPA - No Dialect mapping for JDBC type: 2003

Am getting the below error
No Dialect mapping for JDBC type: 2003; nested exception is org.hibernate.MappingException: No Dialect mapping for JDBC type: 2
Repo Code is as follows
String chrPackageId = "select\n" +
"\tcombination_hr_id as \"chRuleId\",\n" +
"\tcombination_hr_name as \"chRuleName\", \n" +
"\tholdingrule_list as \"selectedRules\"\n" +
"from\n" +
"\tcombination_holding_rule chr\n" +
"where\n" +
"\tpackage_id =:packageId";
#Query(value=chrPackageId,nativeQuery = true)
List<CHRfromPackageIdDTO> repoCHRFromPackageId(int packageId);
DTO object is as below
public interface CHRfromPackageIdDTO {
int getChRuleId();
String getChRuleName();
Integer[] getSelectedRules();
}
We use Postgres DB, there is some issue in getting the Integer[] value actually.
The other answers in Stackoverflow are Hibernate specific. but we use spring-data-jpa.
Entity Class
import com.vladmihalcea.hibernate.type.array.IntArrayType;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.*;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#TypeDefs({
#TypeDef(
name = "string-array",
typeClass = StringArrayType.class
),
#TypeDef(
name = "int-array",
typeClass = IntArrayType.class
),
#TypeDef(name = "json", typeClass = JsonStringType.class),
#TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
#Entity
#Table(name="combination_holding_rule")
public class CombHoldingRule {
#Id
#Column(name="combination_hr_id")//Checked
private Integer combHoldingRuleId;
#Column(name="combination_hr_name")//Checked
private String combHoldingRuleName;
#Column(name="jurisdiction_id")//Checked
private Integer jurisdictionId;
#Column(name="function_group_id")//Checked
private Integer functionGroupId;
#Column(name="overall_netting_type")//Checked
private String overallNettingType;
#Column(name="package_id")//Checked
private Integer packageId;
#Type(type = "int-array")
#Column(
name = "holdingrule_list",
columnDefinition = "integer[]"
)
private int[] holdingRuleList;
}
In Repository
#Query(value="from CombHoldingRule where packageId=:packageId")
List<CombHoldingRule> repoCHRFromPackageId(#Param("packageId") int packageId);
I took the result from JPAQuery into the Entity , then did the below in the Service Layer
public List<CHRfromPackageIdDTO> getCHRFromPackageIdService(int packageId) {
List<CombHoldingRule> combHoldingRuleList = combinationHRrepo.
repoCHRFromPackageId(packageId);
List<CHRfromPackageIdDTO> combDTO = new ArrayList<>();
for ( CombHoldingRule combHoldingRule : combHoldingRuleList) {
CHRfromPackageIdDTO temp = new CHRfromPackageIdDTO(combHoldingRule.getCombHoldingRuleId(),
combHoldingRule.getCombHoldingRuleName(),
combHoldingRule.getHoldingRuleList());
combDTO.add(temp);
}
return combDTO;
}
Also pls check HERE
Note: This is kind of work around I believe, really not sure , how to directly take value from a native query into a custom Pojo instead of an entity class. I really appreciate if anyone post the answer for that. I would accept that as the Answer.

#Query does not give desired result when native query is used

iam using spring data jpa in my project
package com.mf.acrs.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Data
#Entity(name= "mv_garage_asset_mapping")
public class GarageAssetMapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2535545189473989744L;
#Id
#Column(name="GARAGE_CODE")
private String garageCode;
#Column(name="GARAGE_NAME")
private String garageName;
#Column(name="GARAGE_ADDRESS")
private String garageAddress;
#Column(name="GARAGE_BRANCH")
private String garageBranch;
#Column(name="CONTRACT_NUMBER")
private String contractNumber;
}
this is my entity object
package com.mf.acrs.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.mf.acrs.model.GarageAssetMapping;
public interface GarageAssetMappingRepository extends JpaRepository<GarageAssetMapping, String> {
// #Query(name="select u.CONTRACT_NUMBER from mv_garage_asset_mapping u where u.GARAGE_CODE = ?1", nativeQuery = true) //**QUERY 1**
#Query("select u.contractNumber from mv_garage_asset_mapping u where u.garageCode = ?1") // **QUERY 2**
List<String> findByGarageCode(String garageCode);
}
this is my repository interface
when i use the QUERY 1 in my application the query fired by spring data jpa is
Hibernate: select garageasse0_.garage_code as garage_code1_2_, garageasse0_.contract_number as contract_number2_2_, garageasse0_.garage_address as garage_address3_2_, garageasse0_.garage_branch as garage_branch4_2_, garageasse0_.garage_name as garage_name5_2_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
but when i use QUERY 2 the query fired is
Hibernate: select garageasse0_.contract_number as col_0_0_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
QUERY 2 gives me desired result.
but my question is why spring data jpa fires a incorrect query in 1st case.
in QUERY 1 hibernate tries to pull all the data fields despite the fact i have explicitly written in query that i want to fetch only one field.
What mistake iam doing in this case?
The method defined in the controller which calls the method is below:
#PostMapping("/searchAssetsAjax")
#ResponseBody
public String searchAssetsAjax(#RequestBody SearchAssetData searchAssetData) throws IOException{
System.out.println("iam in the searchAssetsAjax "+searchAssetData);
System.out.println("iam in the searchAssetsAjax "+searchAssetData.toString());
// System.out.println("throwing exceptions" ); throw new IOException();
System.out.println("hitting the db "+searchAssetData.getGarageCode());
// List<String> contractNums = garageAssetMapRepository.findContractNumberByGarageCode(searchAssetData.getGarageCode());
List<String> contractNums = garageAssetMapRepository.findByGarageCode(searchAssetData.getGarageCode());
System.out.println("############contract num size is "+contractNums.size());
for(String contract: contractNums) {
System.out.println("contract nums are "+contract);
}
return "success";
}

Jpa Repository got error cannot not serializable when get data from database

I have a problem when try to get data using JPA Repository,
every time i try to get data always get error java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable,
i have tried to explorer the solution, but until now still not found any clue to solve this problem
here my error :
2019-04-03 07:36:17.434 ERROR 19348 --- [nio-5001-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable] with root cause
java.lang.ClassCastException: shurl.model.Shurl cannot be cast to java.io.Serializable
and here my code at jpa repository
package shurl.repository
import shurl.model.Shurl
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import org.springframework.data.domain.Pageable
import org.springframework.data.domain.Page
import java.time.LocalDate
import java.time.LocalDateTime
import shurl.model.ShurlHistory
#Repository
interface ShurlHistoryRepository : JpaRepository<ShurlHistory, String> {
#Query("select b.* from shurl a " +
"left join shurl_history b on b.shurl_code = a.shurl_code " +
"where a.shurl_code = :code",nativeQuery = true )
fun findShurlHistory(code:String):List<ShurlHistory>?
}
and here my model
package shurl.model
import com.fasterxml.jackson.annotation.JsonIgnore
import javax.persistence.*
import org.apache.poi.hpsf.Decimal
import java.time.LocalDate
import java.sql.Blob
import org.hibernate.type.BlobType
import java.time.LocalDateTime
#Entity
#Table(name = "shurl_history", schema = "dbo")
data class ShurlHistory (
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = true)
var id:Long?=null,
#Column(name = "create_date", nullable = false )
var createDate:LocalDateTime = LocalDateTime.now(),
#ManyToOne
#JoinColumn(name = "shurl_code", referencedColumnName = "shurl_code", nullable = true)
var shurl : Shurl? = null
)
can someone help me?
If you reference another object using non-primary key column, make the referenced object serializable.
It's a known bug reported in 2012 and still unsolved.
Make Shurl serialzable and it should work:
#Entity
public class Shurl implements Serializable {
private static final long serialVersionUID = 1L;
}
i think i have found the solution without serializable, i remove id properties in class shurl and i set shurl_code as primary key..

Hibernate Query Returning only one value

I am trying to create a Spring Hibernate App and I am accessing a table that has the following values:
select REPAIR_STATUS_CD,STATUS_DATE
from repair_status
where REPAIR_CONF_NO ='1234567';
REPAIR_STATUS_CD STATUS_DATE
----- -------------------- -
NEWO 25-FEB-2016 20:07:45
RLSD 25-FEB-2016 20:07:45
REQA 25-FEB-2016 20:13:24
URCD 26-FEB-2016 19:43:40
UINS 26-FEB-2016 19:43:45
UBER 27-FEB-2016 09:42:59
RQT6 27-FEB-2016 09:46:28
RQXP 03-MAR-2016 12:24:43
RBER 04-MAR-2016 21:52:22
SPCM 09-MAY-2016 18:13:33
SCOM 10-MAY-2016 19:09:54
Now in the DAOImpl Class I am fetching the same using the below code.
Session session = sessionFactory.getCurrentSession();
session.beginTransaction();
Query<RepairStatus> query = session.createQuery("from RepairStatus where repairConfNo = '"+repairConfNo+"' ");
List<RepairStatus> repairStatusList = query.getResultList();
System.out.println("Inside Repair Status Service");
for(RepairStatus repairStatus: repairStatusList){
System.out.println(repairStatus.getRepairStatusCode());
}
But when I print the output using the sysout and the for loop I am getting the following:
Inside Repair Status Service
NEWO
NEWO
NEWO
NEWO
NEWO
NEWO
NEWO
NEWO
NEWO
Why are the rows getting repeated although the database has proper values.
Thanks a lot in advance :)
Also this is my Entity Class
package com.gsx.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="TG_REPAIR_STATUS")
public class RepairStatus {
#Id
#Column(name="REPAIR_CONF_NO")
private String repairConfNo;
#Column(name="REPAIR_STATUS_CD")
private String repairStatusCode;
#Column(name="STATUS_DATE")
private Date statusDate;
public void setStatusDate(Date statusDate) {
this.statusDate = statusDate;
}
public String getRepairConfNo() {
return repairConfNo;
}
public void setRepairConfNo(String repairConfNo) {
this.repairConfNo = repairConfNo;
}
public Date getStatusDate() {
return statusDate;
}
public String getRepairStatusCode() {
return repairStatusCode;
}
public void setRepairStatusCode(String repairStatusCode) {
this.repairStatusCode = repairStatusCode;
}
}
You should replace
Query<RepairStatus> query = session.createQuery("from RepairStatus where repairConfNo = '"+repairConfNo+"' ");
to
Query<RepairStatus> query = session.createQuery("from RepairStatus where repairConfNo =:repairConfNo");
parameterQuery.setParameter("repairConfNo", you_repairConfNo);
List<RepairStatus> repairStatusList = query.getResultList();
Query is look good, you need to enable the show_sql
if your are using hibernate.cfg.xmlthen you can enable the sql like
<property name="show_sql">true</property>
then debug the generated sql by hibernate, it can help you to find out the issue.
Also your table name is TG_REPAIR_STATUS
#Table(name="TG_REPAIR_STATUS")
public class RepairStatus
and you are running query
select REPAIR_STATUS_CD,STATUS_DATE
from repair_status
where REPAIR_CONF_NO ='1234567';
on repair_status table instead of TG_REPAIR_STATUS table, please verify this on your database

Moving Spring Boot 1.3 to 1.4, Hibernate 4 to 5, Pascal Case Issues

I created a Spring Boot 1.3.5 POC with Spring Data JPA and Hibernate (4.3.11.Final in this version of Spring Boot). My backend database is Microsoft SQL Server, and our standard naming convention for database objects is pascal case (e.g. MySchema.MyTable.MyColumn). I used the javax.persistence.Table and javax.persistence.Column annotations to set the names, and added spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy to my application.properties file.
Everything worked perfectly. I even updated to Spring Boot 1.3.6 with no issues.
Now I moved to Spring Boot 1.4.0.RELEASE which uses Hibernate 5.0.9.Final, and the spring.jpa.hibernate.naming-strategy property is deprecated in favor of spring.jpa.hibernate.naming.strategy. I changed that property name, but left the EJB3NamingStrategy value. I also changed the other deprecated elements:
org.springframework.boot.orm.jpa.EntityScan to org.springframework.boot.autoconfigure.domain.EntityScan
org.springframework.boot.context.web.SpringBootServletInitializer to org.springframework.boot.web.support.SpringBootServletInitializer
org.springframework.boot.test.SpringApplicationConfiguration to org.springframework.boot.test.context.SpringBootTest (in my test classes)
Now the generated SQL uses the default camel case to underscore naming convention and not the pascal case that I had with EJB3NamingStrategy.
//application.properties
spring.data.jpa.repositories.enabled=true
spring.data.solr.repositories.enabled=false
spring.data.mongodb.repositories.enabled=false
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.naming.strategy=org.hibernate.cfg.EJB3NamingStrategy
#spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy
//hibernate.properties
hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.format_sql=true
//Principal.java
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import org.hibernate.envers.AuditTable;
import org.hibernate.envers.Audited;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Entity
#Table(name="Principal", schema="Security")
#Audited
#AuditTable(value = "Principal", schema = "Audit")
public class Principal {
private static final Logger LOG = LoggerFactory.getLogger(Principal.class);
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "Id",
nullable = false)
private Long id;
#Column(name = "Username",
nullable = false,
unique = true)
#Size(min = 1, max = 64)
private String name;
#Column(name = "FirstName",
nullable = false)
#Size(min = 1, max = 64)
private String firstName;
#Column(name = "LastName",
nullable = false)
#Size(min = 1, max = 128)
private String lastName;
#Column(name = "IsEnabled",
nullable = false)
private boolean enabled;
//getters/setters omitted for brevity
}
orignal console output:
Hibernate:
select
principal0_.Id as Id1_8_,
principal0_.IsEnabled as IsEnable2_8_,
principal0_.FirstName as FirstNam3_8_,
principal0_.LastName as LastName4_8_,
principal0_.Username as Username5_8_
from
Security.Principal principal0_
where
principal0_.Username=?
new console output:
Hibernate:
select
principal0_.id as id1_7_,
principal0_.is_enabled as is_enabl2_7_,
principal0_.first_name as first_na3_7_,
principal0_.last_name as last_nam4_7_,
principal0_.username as username5_7_
from
security.principal principal0_
where
principal0_.username=?
2016-08-05 09:19:22.751 WARN 5032 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 207, SQLState: S0001
2016-08-05 09:19:22.751 ERROR 5032 --- [ XNIO-2 task-8] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid column name 'is_enabled'.
2016-08-05 09:19:22.768 ERROR 5032 --- [ XNIO-2 task-8] io.undertow.request : UT005023: Exception handling request to /springbootsecurity/login
I've searched extensively, and found references to ImplicitNamingStrategy and PhysicalNamingStrategy; but plugging those in don't seem to work and is probably not the correct approach. I've also seen references to creating my own NamingStrategy. Is that the route I must take?
Is there a different setting for Hibernate 5 that will use the exact name I provide in the #Table and #Column annotations?
Is there a problem with the way I am defining the annotations?
I would like to say I ended up posting a silly question, but every direction I went talked about creating a custom naming strategy. The answer in my case, however, was simply using Hibernate's PhysicalNamingStrategyStandardImpl.
Added to application.properties:
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
From my naive analysis, I'm assuming this works because I am using the #Table and #Column annotations. The PhysicalNamingStrategyStandardImpl appears to simply use the name in those annotations as the database object name.
So my Hibernate generated query is once again formatted as:
Hibernate:
select
principal0_.Id as Id1_7_,
principal0_.IsEnabled as IsEnable2_7_,
principal0_.FirstName as FirstNam3_7_,
principal0_.LastName as LastName4_7_,
principal0_.Username as Username5_7_
from
Security.Principal principal0_
where
principal0_.Username=?
Reading #AmanTuladhar's link and this link from that post is where it eventually clicked for me. Thanks!
this is really a nice thread , for a beginner - who are migrating from spring boot 1.3 to 1.4 - below link contains all the stranded changes required , it also list all the deprecated options and contains some examples as well .
It gives overview about almost everything that you can use with application. For ex- Hibernate , Log4j , Junit/Mockito , Integration and so on . Please follow below link
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes

Resources