This is a spring boot 2 application.
An entity having 2 named queries, which is throwing exception while starting the server like "Caused by: org.hibernate.DuplicateMappingException: Duplicate query mapping EstCredentials.findAppDepartment"
#Entity
#Table(name = EntityConstants.TABLE_EST_CREDENTIALS)
#NamedNativeQueries({
#NamedNativeQuery(name = "Credentials.findAppDepartment", query = "SELECT (deptmast.deptid) as deptId, deptname as deptName"
+ " FROM deptmast, doctdept" + " WHERE deptmast.deptid = doctdept.deptid ", resultSetMapping = "APP_DEPARTMENT"),
#NamedNativeQuery(name = "Credentials.findAppClinic", query = "SELECT A.DOCTDEPTID as doctdeptId, A.DOCTDEPTNAME as doctDeptName, "
+ " FROM DOCTDEPT A, DEPTMAST B"
+ " WHERE A.WORKING = 1", resultSetMapping = CommonConstants.APP_CLINIC_RESULT_MAP) })
#SqlResultSetMappings({
#SqlResultSetMapping(name = "APP_DEPARTMENT", classes = {
#ConstructorResult(targetClass = InstituteDepartmentDto.class, columns = {
#ColumnResult(name = "deptId", type = Long.class),
#ColumnResult(name = "deptName", type = String.class) }) }),
#SqlResultSetMapping(name = CommonConstants.APP_CLINIC_RESULT_MAP, classes = {
#ConstructorResult(targetClass = InstituteDoctorDepartmentDto.class, columns = {
#ColumnResult(name = "docDeptId", type = Long.class),
#ColumnResult(name = "doctDeptname", type = String.class) }) })
})
public class Credentials {
private Long estCode;
private String dbUserName;
private String dbPassword;
public Credentials() {
}
}
Let me know if need any other details.
Generally, it pays to assume that error messages are right.
In this case, you have a duplicate mapping for a query named: "EstCredentials.findAppDepartment". You defined this name in CommonConstants.APP_DEPARTMENT_RESULT_MAP and then use it twice, for two different mappings.
Related
I'm trying to create a inline function that can return entity column name, but get error when i try to filter list of memberProperties from a instance class that i create
This is the error i get :
Expected type mismatch: inferred type is KProperty1<out Any!, Any?>? but KProperty1<T, *>? was expected
i try the tutorial from this Create a class instance using a string containing the package name and class name
Here is my entity:
#Entity
#Table(name = "employee", schema = "dbo")
data class Employee(
#Id
#Column(name = "id", nullable = false, length = 20)
var id: String,
#Column(name = "employee_name", nullable = true, length = 30)
var employeeName: String? = "",
#ManyToOne
#JoinColumn(name = "dept_code", referencedColumnName = "dept_code", nullable = true)
var dept: MasterDept? = null
)
#Entity
#Table(name = "ms_dept", schema = "dbo")
data class MasterDept(
#Id
#Column(name = "dept_code", nullable = false, length = 20)
var code: String,
#Column(name = "dept_desc", nullable = true, length = 100)
var desc: String? = "",
#ManyToOne
#JoinColumn(name = "div_code", referencedColumnName = "div_code", nullable = true)
var div: MasterDiv? = null
)
#Entity
#Table(name = "ms_div", schema = "dbo")
data class MasterDiv(
#Id
#Column(name = "div_code", nullable = false, length = 20)
var code: String,
#Column(name = "div_desc", nullable = true, length = 100)
var desc: String? = ""
)
i try to get column name from property desc of entity MasterDept or MasterDiv, depend of usage
here is my function :
inline fun <reified T : Any> getColumnName(filt:String):String {
var listFilter:List<String> = listOf();
if(filt.contains(".", true)){
listFilter = filt.split(".")
filt = listFilter.get(0)
}
var property = T::class.memberProperties.filter { prop -> prop.name == filt}.firstOrNull()//here is working
var colName : String = ""
var tableName:String = ""
if(listFilter.size > 1){
var idx:Int = 1
for(item : String in listFilter) {
if(idx < listFilter.size){
val cls = Class.forName(property!!.returnType.toString()).kotlin
var table = cls.annotations.find { it.annotationClass == Table::class } as? Table
tableName = table!!.name
property = cls.memberProperties.filter { prop -> prop.name == listFilter.get(idx)}.firstOrNull() //error in here
}
idx++
}
}
var field = property!!.javaField!!
var column = field.getAnnotation(Column::class.java)
return tableName + "." + column!!.name()
}
filt parameter sometimes is "employeeName", "dept.desc" or "dept.div.desc"
am i missing something??
I would be glad for any help.
Kotlin is a strongly typed language. You can't declare a variable with a type KProperty1<T, *>? and reassign it with a value of type KProperty1<out Any, *>? (because the latter is not a subtype of the former). Actually, you haven't declared these types explicitly; they were inferred by the compiler.
Not sure what's going on in this code (and if it is possible to avoid mutation of the property variable, which is preferrable), but you can fix this error by declaring property's type as KProperty1<*, *>?, which is a supertype of all other KProperty1 types; also its declaration could be simplified:
var property: KProperty1<*, *>? = T::class.memberProperties.firstOrNull { it.name == filt }
I'm trying to create a inline function that can return entity column name, but get error
I created that from the solution i found on Annotation reflection (using getAnnotation) does not work
Here is my entity:
#Entity
#Table(name = "employee", schema = "dbo")
data class Employee(
#Id
#Column(name = "id", nullable = false, length = 20)
var id: String,
#Column(name = "employee_name", nullable = true, length = 30)
var employeeName: String? = "",
)
Here is my function :
inline fun <reified T : Any> getColumnName(filt:String):String {
var property = T::class.memberProperties.filter { prop -> prop.name == filt}.firstOrNull()
var field = property!!.javaField!!
var column = field.getAnnotation(Column::class) //error in here
return column!!.name()
}
When i try this,
var column = field.getAnnotation(Column.class)
error :
Name expected
When i try this,
var column = field.getAnnotation(Column::class)
error :
Type inference failed: fun <T : Annotation!> getAnnotation(p0: Class<T!>!): T!
cannot be applied to
(KClass<Column>)
Type mismatch: inferred type is KClass<Column> but
Class<(???..???)>! was expected
am i missing something??
I would be glad for any help.
I have requirement to call store procedures which takes input parameters. This store procedure returns custom result set, that result set i need to read and process further before return to UI. How we can achieve this?
EG:
#Query("CALL SP_EMPLOYEE_REPORT(:year)",nativeQuery = true)
List<EmpolypeeCustomReportBean> getEmployeeReport(#param("year") Integer year);
Given the following stored procedure.
CREATE PROCEDURE NAME_OF_THE_PROCEDURE(IN param VARCHAR(255), OUT retval INT)
You can call it from interface query:
#Procedure(value = "NAME_OF_THE_PROCEDURE")
int getFromStoredProcedure(String param);
Also by #Query annotation:
#Query(value = "CALL NAME_OF_THE_PROCEDURE(:input_value);", nativeQuery = true)
Integer findSomeThing(#Param("input_value") Integer name);
Or you can use named stored procedure query too.
#Entity
#NamedStoredProcedureQuery(name = "MyObj.getSomethingFromProc",
procedureName = "NAME_OF_THE_PROCEDURE", parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, name = "param", type = String.class),
#StoredProcedureParameter(mode = ParameterMode.OUT, name = "retval", type = Integer.class)})
public class MyObj{
// class definition
}
Then call it.
#Procedure(name = "MyObj.getSomethingFromProc")
Integer getSomethingFromStoredProc(#Param("param") String model);
Also you can use resultClasses and resultSetMapping properties in #NamedStoredProcedureQuery for complex return types.
Complex example provided by Eclipselink:
#NamedStoredProcedureQuery(
name="ReadUsingMultipleResultSetMappings",
procedureName="Read_Multiple_Result_Sets",
resultSetMappings={"EmployeeResultSetMapping", "AddressResultSetMapping", "ProjectResultSetMapping", "EmployeeConstructorResultSetMapping"}
)
#SqlResultSetMappings({
#SqlResultSetMapping(
name = "EmployeeResultSetMapping",
entities = {
#EntityResult(entityClass = Employee.class)
}
),
#SqlResultSetMapping(
name = "EmployeeConstructorResultSetMapping",
classes = {
#ConstructorResult(
targetClass = EmployeeDetails.class,
columns = {
#ColumnResult(name="EMP_ID", type=Integer.class),
#ColumnResult(name="F_NAME", type=String.class),
#ColumnResult(name="L_NAME", type=String.class),
#ColumnResult(name="R_COUNT", type=Integer.class)
}
)
}
)
})
public Employee(){
....
}
I am using Spring Data JPA with native queries like below
public interface ItemRepository extends JpaRepository<ItemEntity, Long> {
#Query(value = "select * from items i where i.category = :itemCategory and i.item_code = :itemCode", nativeQuery = true)
Page<ItemEntity> search(#Param("itemCategory") String itemCategory, #Param("itemCode") String itemCode, Pageable pageable);
}
Now, my use case is
It itemCode is available, only the item with that code from that category should be returned.
But if itemCode is not available then all items in that category should be returned.
So the problem with the above category is when itemCode is passed as NULL no data is returned since it does not match anything. whereas the requirement is it should be ignored.
So is there a way to optionally add a clause to Spring Data JPA native query. I know it is possible with CriteriaQuery but can we do something similar for native queries?
Thanks
Yes, it's feasible with native query too. Very Good explanation here read this
#Approach1
#NamedQuery(name = "getUser", query = "select u from User u"
+ " where (:id is null or u.id = :id)"
+ " And :username"
:itemCode is null or i.item_code = :itemCode
#Approach2
# UserDao.java
public User getUser(Long id, String usename) {
String getUser = "select u from user u where u.id " + Dao.isNull(id)
+ " And u.username " + Dao.isNull(username);
Query query = Dao.entityManager.createQuery(getUser);
}
# Dao.java
public static String isNull(Object field) {
if (field != null) {
if (field instanceof String) {
return " = " + "'" + field + "'";
} else {
return " = " + field;
}
} else {
return " is NULL ";
}
}
How to handle null value of number type in JPA named query
Just modify the where condition
i.item_code = :itemCode
to
:itemCode is null or i.item_code = :itemCode
How to return a json object instead of a json string array using SqlResultSetMappings or ResultTransformer. Here is the output i got when using SqlResultSetMappings or ResultTransformer
[
"Mel Bale ",
"B.A.",
"Interior Designer",
"Daosa",
"n/a"
]
what i want is like this
{
"name":"Mel Bale ",
"qualification":"B.A.",
"Job":"Interior Designer",
"location":"Daosa",
"phone":"n/a"
}
You need to define #SqlResultSetMappings like this so that your data are mapped as JSON
#SqlResultSetMapping(
name = "findAllDataMapping",
classes = #ConstructorResult(
targetClass = Sample.class,
columns = {
#ColumnResult(name = "name"),
#ColumnResult(name = "qualification"),
#ColumnResult(name = "Job"),
#ColumnResult(name = "location"),
#ColumnResult(name = "phone")
}
)
)