Spring data jpa exception - java

While retrieving records from the DB table we are getting exceptions. I tried the same for another table it worked but for this table, it's not working. I am using spring-data-jpa
#Entity
#Table(name=USR.TABLE_NAME)
public class USR implements Serializable {
private static final long serialVersionUID = 1L;
public final static String TABLE_NAME = "usr_profile";
#Id
#Column (name="USR_NO")
private Integer usrNo;
#Column (name="USR_Address", length=20, nullable=true, unique=false)
private Integer usrAddress;
#Column (name="USR_COUNTRY", nullable=true, unique=false)
private String usrCountry;
other fields constructor, no-arg constructor, getter and setter removed for brevity
#Repository
public interface USRRepository extends JpaRepository<USR, Integer> {
#Query("SELECT o.usrNo, o.usrAddress, o.usrCountry, o.usrState, o.usrSt FROM USR o WHERE o.usrNo=?1")
USR findUsrRecordByUsrNo(Integer usrNo);
}
Here I have created a Controller class that has a get mapping
#GetMapping ("/CmpUsr")
public ResponseEntity<String> cmpLookup() {
USR us = usrRepository.findUsrRecordByUsrNo(12557);
return new ResponseEntity<>(us.toString(), HttpStatus.OK);
}
I am getting this exception
SEVERE: Servlet.service() for servlet [dispatcherServiet] in context with path[] threw exception (Request processing failed; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [com.newprof.userApp.domain.USR] for value (12557, 115 Minesota Yellow Rd, US, PH, 000991); nested exception is
org.springframework.core.comvert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Integer to type [com.newprof.userApp.domain.USR]] with root cause

Try this code. I think the problem is the return object witch is not the same with select values.
#Repository
public interface USRRepository extends JpaRepository<USR, Integer> {
#Query("SELECT o FROM USR o WHERE o.usrNo=?1")
USR findUsrRecordByUsrNo(Integer usrNo);
}

Change this:
#Query("SELECT o.usrNo, o.usrAddress, o.usrCountry, o.usrState, o.usrSt FROM USR o WHERE o.usrNo=?1")
USR findUsrRecordByUsrNo(Integer usrNo);
}
with this:
#Query("SELECT new com.newprof.userApp.domain.USR(o.usrNo, o.usrAddress, o.usrCountry, o.usrState, o.usrSt) FROM USR o WHERE o.usrNo=?1")
USR findUsrRecordByUsrNo(Integer usrNo);
}
In exception it says: Failed to convert from type [java.lang.Object[]] to type [com.newprof.userApp.domain.USR].
Which basically means that your query statement returns an object array: java.lang.Object[].
So my plan is, you call your USR constructor straightaway in your query.
EDIT
FOUND THE ANSWER.
So you added this into your query:
new com.newprof.userApp.domain.USR(o.usrNo, o.usrAddress, o.usrCountry, o.usrState, o.usrSt)
And it now says to you: Cannot resolve constructor com.newprof.userApp.domain.USR(). IT IS RUGHT. Because there is no such constructor. You need to add it to your entity.
You need to add something like this:
public USR (Integer usrNo, Integer usrAddress, String usrCountry, String usrState, String usrSt) {
this.usrNo = usrNo;
this.usrAddress = usrAddress;
this.usrCountry = usrCountry;
this.usrState = usrState;
this.usrSt = isrSt;
}
This brand new Constructor will be called in statement new com.newprof.userApp.domain.USR(o.usrNo, o.usrAddress, o.usrCountry, o.usrState, o.usrSt) :D

Related

JPA Converter unnessecary call of "convertToDatabaseColumn" leads to ClassCastException

I have a Converter to convert the String stored in the DB to the corresponding Enum element:
#Converter(autoApply=true)
public class DokumentTypConverter implements AttributeConverter<DokumentTypSchluessel, String> {
#Override
public String convertToDatabaseColumn(DokumentTypSchluessel attribute) {
return attribute.getValue();
}
#Override
public DokumentTypSchluessel convertToEntityAttribute(String dbData) {
return DokumentTypSchluessel.from(dbData);
}
}
I have an Entity class which has a field of the Enum type:
#Entity
#Table(name="REF_DOKUMENTTYPEN")
public class DokumentTyp {
private DokumentTypSchluessel schluessel;
// snip
}
Now when I try to retrieve an instance of that entity from the db
String query = "SELECT d FROM DokumentTyp d WHERE d.schluessel = " + VORBEREITUNG;
entityManager.createQuery(query, DokumentTyp.class).getSingleResult();
I get the following error:
javax.persistence.PersistenceException: An exception occurred while calling convertToDatabaseColumn on converter class de.drvbund.pub.model.convert.DokumentTypConverter with value VORBEREITUNG
at org.eclipse.persistence.mappings.converters.ConverterClass.convertObjectValueToDataValue(ConverterClass.java:139)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:778)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getFieldValue(QueryKeyExpression.java:420)
at org.eclipse.persistence.internal.expressions.ConstantExpression.printSQL(ConstantExpression.java:152)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2241)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.RelationExpression.printSQL(RelationExpression.java:899)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.translateExpression(ExpressionSQLPrinter.java:325)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1755)
at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3268)
at org.eclipse.persistence.platform.database.OraclePlatform.printSQLSelectStatement(OraclePlatform.java:967)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:843)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:854)
at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:815)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.prepareSelectAllRows(StatementQueryMechanism.java:315)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1723)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:904)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:835)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:673)
... 151 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to de.drvbund.pub.enums.DokumentTypSchluessel
I guess the framework takes the toString()-representation of the Enum element from the query, assumes it is the entity attribute value, that needs to be converted to its corresponding dbValue and tries to call the convertToDatabaseColumn() method passing the String. I just don't know how to do this correctly.
How can I retrieve entities filtered by an Enum attribute value with JPA?
The problem was solved by the suggestion of Chris:
entityManager.createQuery("SELECT d FROM DokumentTyp d WHERE d.schluessel = ?1", DokumentTyp.class)
.setParameter(1, DokumentTypSchluessel.VORBEREITUNG)
.getSingleResult();

Java - JPA-Specification: how to create criteria/specification on a field that belongs to a nested object?

I am using jdk 1.8 , hibernate and jpa in my project. And using specification/criteria to build my search query.
I have a class A ( an hibernate entity) which has class B as an attribute. So, roughly, it looks like :
#Entity
class A {
Long id;
String comment;
#OneToOne
B b;
}
and...
#Entity
class B {
Long id;
String type;
}
My repository class looks like (roughly):
public interface ARepository extends PagingAndSortingRepository<A, Integer>,
JpaSpecificationExecutor<A> {
}
Most of the simple JPA queries are working as expected. Even the specification/criteria based directly on Class A is working. However, I need to create a dynamic query and that should be executed under "findAll" method of PagingAndSortingRepository class. This query should be equivalent to
select * from A a left join B b on a.b_id = b.id
where b.type='final' and a.comment='blah';
I created a similar logic as above in a specification like :
public Specification<A> getSpecification() {
return (itemRoot, query, criteriaBuilder) -> {
.........
List<Predicate> partialQueries = new ArrayList<>();
partialQueries.add(criteriaBuilder.equal(itemRoot.get("b.type"), "final"));
partialQueries.add(criteriaBuilder.equal(itemRoot.get("comment"), "blah"));
//Other queries to be added...
return criteriaBuilder.and(partialQueries.toArray(new Predicate[0]));
};
}
And getting error :
Unable to locate Attribute with the the given name [b.type] on this ManagedType [com.something.domain.A]
Any insight on how to create criteria/specification on a field that belongs to a nested object?
If you want to filter nested object. You can write
itemRoot.get("NestedTableName").get("nestedfieldname")
In your case - itemRoot.get("B").get("type")
itemRoot.get("Name of the nested object field in the root class").get("nestedfieldname");
Example:
cb.equal(root.get("b").get("type"),value)
In your case - itemRoot.get("b").get("type");

java.lang.ClassCastException: java.lang.String cannot be cast to com.security.model.UserRequest

Am retriving UserRequest object from DB using JPA Query as following.
#Query("SELECT req.supervisorEmail from User u, UserRequest as req WHERE u.username = req.userRequestName and req.userRequestRole= '4' and u.active=true")
public List<UserRequest> getSupervisorEmailIds();
Am having the UserRequest POJO class as follows.
public class UserRequest implements Identifiable<Long>, LazilyLoadable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#JsonIgnore
private Long id;
#Column(name = "supervisor_email")
private String supervisorEmail;
#Column(name="user_request_name")
private String userRequestName;
#Column(name="user_request_role")
private String userRequestRole;
}
when am trying to iterating over the UserRequest object am getting the ClassCastException for the below code.
List<UserRequest> supervisorEmailIds = userService.getSupervisorEmailIds();
for(UserRequest s: supervisorEmailIds) { // throwing exception on this line.
if(s!=null) {
System.out.println("Printing -->"+s.getSupervisorEmail());
}
System.out.println("Null error");
}
Following is the error am getting.
2019-02-22 00:34:26,719 [http-9191-1] ERROR com.cat.pscs.api.controller.BaseController: 83 - Unhandled exception while processing request for URL : http://localhost:9191/security/users/get-supervisor-emailids with exception : java.lang.String cannot be cast to com.cat.pscs.security.model.UserRequest
java.lang.ClassCastException: java.lang.String cannot be cast to com.cat.pscs.security.model.UserRequest
at com.cat.pscs.security.controller.UserController.getSupervisorEmailIds(UserController.java:320)
Are you sure that below line returns UserRequestList? I think it returns list of strings
List<UserRequest> supervisorEmailIds = userService.getSupervisorEmailIds();
just change your sql query that returns list of UserRequest object .
Your query returns list of String, while you expect to get list of UserRequest. Changing query as follow should do the job:
#Query("SELECT req from User u, UserRequest as req WHERE u.username = req.userRequestName and req.userRequestRole= '4' and u.active=true")
Inside #Query you wrote
SELECT req.supervisorEmail from User u, UserRequest as req...
I suppose supervisorEmail is a VARCHAR or CHAR table column.
You're extracting only a single String column.
If you want UserRequest(s), you need
SELECT req from User u, UserRequest as req...

Spring Boot + MongoRepository, get all rows but only certain fields

I'm trying to fetch all the entries in my database, but only the reference fields. In my MongoRepository, I want to use a custom query, so it doesn't use the method name to build up the query. The following doesn't seem to work:
public interface JvRepository extends MongoRepository<Jv, String> {
#Query(value = "{}", fields = "{ id : 0, reference : 1 }")
public List<String> findAllJvReferences();
}
public class Jv {
#Id
private String id;
private String reference;
}
The error is:
Jv cannot be cast to java.lang.String
I tell it to not get the id, and do get the reference right? Why does it not return a String, but still a Jv?
I guess I should pass something in the value that tells Mongo to select everything, but I have no idea what. Or is there something else wrong with this code?

JPA enum query ERROR on playframework

I am working on project using java playframework 1.2.4 and I have a #Entity class. It is look like
#Entity
public class EmployeeType extends Model {
public static enum TYPE { HOURLY, DAILY, MONTHLY };
public static enum NATIONALITY { LOCAL, FOREIGN };
#Required
#Enumerated(EnumType.STRING)
public TYPE type;
#Required
#Enumerated(EnumType.STRING)
public NATIONALITY nationality;
}
And in my controller class I want to get list of EmployeeTypes using my 2 enum attributes.
Query looks like
Query query = JPA.em().createQuery("SELECT e FROM EmployeeType e where " +
"e.nationality = :nationality " +
"and e.type = :type");
query.setParameter("nationality", NATIONALITY.LOCAL);
query.setParameter("type", TYPE.HOURLY);
List<models.EmployeeType> employeeType = query.getResultList()
Gives this error: IllegalArgumentException occured : Parameter value [LOCAL] was not matching type [models.EmployeeType$NATIONALITY]
What should i do?
The error is possibly because of the fact that your enums are nested in your entity. You need to access it on entity name.
You can change your setParameter code to: -
query.setParameter("nationality", EmployeeType.NATIONALITY.LOCAL);
query.setParameter("type", EmployeeType.TYPE.HOURLY);

Categories

Resources