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
Related
I've a spring boot application which is supposed to call an oracle stored procedure but when I send a request it returns 200 Ok with no payload returned. here is my code on how I called the oracle stored procedure.
#application.properties file
server.port=3000
spring.datasource.url=jdbc:oracle:thin:#xxxxxxxxx
#thin is popular oracle driver, localhost is the host of the database, 1521 is the port of the database, and xe is the database name
spring.datasource.username=XXXXXX
spring.datasource.password=XXXXXX
spring.datasource.driver-class-name= oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.properties.hibernate.proc.param_null_passing=true
#my repo class to call the stored procedure
package com.amsadmacc.amsadmaccadapter.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
#Data
#Entity
#NoArgsConstructor
#Builder
#AllArgsConstructor
#NamedStoredProcedureQuery(
name = "test_stored_proc_sp",
procedureName = "Test_stored_proc"
)
public class PathwaysJourney implements Serializable {
#Id
private long id;
private Integer pidm;
private String firstName;
private String lastName;
private Integer termCode;
private String termDescription;
private Integer applicationNumber;
private String applicationStatusCode;
private String applicationStatusDescription;
private String applicationProgram;
private String majorCode;
private String majorDescription;
private Date applicationDate;
private Integer daysFromApplication;
private String email;
private String mobileNumber;
}
#my controller
#PostMapping("/pathwaysjourney1")
#ResponseBody
public List getAllPathways1() {
spridenRepo.serverOut();
StoredProcedureQuery proc = this.em.createNamedStoredProcedureQuery("Test_stored_proc");
System.out.println("===>>> start exec");
//String output=serverOut();
//log.info("Output {}",output);
proc.execute();
System.out.println("===>>> end exec");
return proc.getResultList();
}
The above end point in the controller returns an empty string like [] in the response body, I've tested the stored procedure in oracle sql developer it returns data.
Any Idea what the problem is? ,some say it is the " set serveroutput on" command, it should be turned on every time a call is made from spring boot, if so, how do we run that command from spring boot whenever the call is made?
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);
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";
}
I have a spring JPA Application. I am using Spring Boot with Spring JPA native query to fetch the data but I am not getting any results. Database used is Oracle 11g. Can anyone please help me to fix it ?
Here is the code.
Repository
public interface RoseRepository extends JpaRepository {
#Query(value = "SELECT RWM.RIG_WELL_ID as id,RM.RIG_NAME as name FROM RIG_WELL_MASTER RWM JOIN RIG_UNIT_MAPPER RUM ON RWM.fk_rig_master_id = RUM.fk_rig_master_id JOIN RIG_UNIT RU ON ru.rig_unit_code = RUM.UNIT_CODE JOIN RIG_MASTER RM ON RM.RIG_MASTER_ID = RWM.FK_RIG_MASTER_ID AND RWM.START_TIME=TO_DATE(?1,'DD-MON-YY') AND RU.UNIT_NAME=?2", nativeQuery = true)
public List<RigDetails> fetchRigsForAUnit(String startTime,String unitName);
}
interface
public interface RigDetails {
String getId();
String getName();
}
Service
#Service
public class RoseService {
#Autowired
private RoseRepository roseRepository;
public List<RigDetails> fetchRigsForAUnit(String startTime, String unitName) {
List<RigDetails> rigList = null;
try{
rigList = roseRepository.fetchRigsForAUnit(startTime, unitName);
}catch(Exception e){
e.printStackTrace();
}
return rigList;
}
}
I have an Oracle XMLType column that stores the various language specific strings. I need to construct a Hibernate criteria that orders on this column. In order to do this, I need to extract the value with an Oracle function. This criteria is generated automatically by code I have written but I cannot, for the life of me, figure out how to extract the value and order on it via the criteria API. Basically, the generated SQL should look something like:
SELECT EXTRACTVALUE(title, '//value[#lang="EN"]') AS enTitle
FROM domain_object
ORDER BY enTitle
I fiddled with projections momentarily, but they appear to execute a second select. Which I assume would cause hibernate to select ALL values and in memory sort them based on the projection? This would be very undesirable =\
Ok, I found a solution. Not sure this is the best, so I will leave it open for a little while if some one wants to provide a better answer / refine my solution.
What I did was extend org.hibernate.criterion.Order thusly:
package com.mycorp.common.hibernate;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Order;
import org.hibernate.engine.SessionFactoryImplementor;
import com.mycorp.LocalizationUtil;
public class LocalStringOrder extends Order {
private static final long serialVersionUID = 1L;
private boolean ascending;
private String propName;
public LocalStringOrder(String prop, boolean asc) {
super(prop, asc);
ascending = asc;
propName = prop;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propName);
StringBuffer fragment = new StringBuffer();
for ( int i=0; i<columns.length; i++ ) {
SessionFactoryImplementor factory = criteriaQuery.getFactory();
fragment.append( factory.getDialect().getLowercaseFunction() )
.append('(');
fragment.append("EXTRACTVALUE(");
fragment.append( columns[i] );
fragment.append(", '//value[#lang=\"" +
LocalizationUtil.getPreferedLanguage().name() +
"\"')");
fragment.append(')');
fragment.append( ascending ? " asc" : " desc" );
if ( i<columns.length-1 ) fragment.append(", ");
}
return fragment.toString();
}
public static Order asc(String propertyName) {
return new LocalStringOrder(propertyName, true);
}
public static Order desc(String propertyName) {
return new LocalStringOrder(propertyName, false);
}
}
Then it was just a matter of saying criteria.addOrder(LocalStringOrder.asc('prop')).
Another general solution is NativeSQLOrder, see http://opensource.atlassian.com/projects/hibernate/browse/HHH-2381. I do not undestand, why this feature is not in Hibernate yet.