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

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

Related

Spring can't find implementation

Here is my folder structure:
In my IAppUserMapper I have a method to convert every AppUser entity instance to Data Transfer Object Model. Here is the code in IAppUserMapper interface:
import com.server.ecommerceapp.dto.AppUserDTO;
import com.server.ecommerceapp.model.AppUser;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
#Mapper
public interface IAppUserMapper {
IAppUserMapper appUserMapper = Mappers.getMapper(IAppUserMapper.class);
#Mapping(target = "username")
#Mapping(target = "email")
#Mapping(target = "password")
#Mapping(target = "roles", expression = "java(appUser.getRoles().stream().map(this::getRoleName).collect(Collectors.toList()))")
AppUserDTO toAppUserDTO(AppUser appUser);
default String getRoleName(Role role) {
return role.getRoleName();
}
}
And here is the MapperConfiguration class code where I configure both Product and user mappers:
import com.server.ecommerceapp.mapper.IAppUserMapper;
import com.server.ecommerceapp.mapper.IProductMapper;
import org.mapstruct.factory.Mappers;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class MapperConfiguration {
#Bean
public IAppUserMapper appUserMapper() {
return Mappers.getMapper(IAppUserMapper.class);
}
#Bean
public IProductMapper productMapper() {
return Mappers.getMapper(IProductMapper.class);
}
}
The error I get:
Error creating bean with name 'appUserMapper' defined in class path
resource
[com/server/ecommerceapp/configuration/MapperConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [com.server.ecommerceapp.mapper.IAppUserMapper]: Factory
method 'appUserMapper' threw exception; nested exception is
java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot
find implementation for com.server.ecommerceapp.mapper.IAppUserMapper
I was told I should make META-INF package in resources, with service package and the com.server.ecommerceapp.mapper.AppUserMapper txt with the content same as the name of the file, so that Spring can scan and find the package following the path:
src/main/resources/META-INF/service/com.server.ecommerceapp.mapper.AppUserMapper
but it didnt work. Any ideas how to solve this, and by the way, is it bad practise to start interface names with capital I cause Im coming from ASP?
Edit:
I added #Mapper(componentModel = "spring") to my interfaces and implemented them as DI with Autowired. I dont know if its related to that problem that I had but now I get error that it cant find collectors. Im trying to map a collection of Roles from AppUser to AppUserDTO. Here are both AppUser and AppUserDTO classes:
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Data
public class AppUser {
#Id
#GeneratedValue(strategy = IDENTITY)
private Long id;
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "email", nullable = false, unique = true)
private String email;
#Column(name = "password", nullable = false)
private String password;
#ManyToMany(fetch = EAGER)
private Collection<Role> roles;
}
And DTO:
#NoArgsConstructor
#AllArgsConstructor
#Data
public class AppUserDTO {
private String username;
private String email;
private String password;
private Collection<String> roles;
}
So you're using Spring, but you are trying to not use Spring.
You should make your mappers use Spring component model:
#Mapper(componentModel = "spring")
public interface MyMapper {
Target map(Source source);
}
Check docs for dependency injection: https://mapstruct.org/documentation/stable/reference/html/#using-dependency-injection
Or do it with shared configuration: https://mapstruct.org/documentation/stable/reference/html/#shared-configurations
After that you can just #Autowired MyMapper myMapper; as any other Spring bean. No need to create instance in interface (the "Mappers.getMapper" thing) and no need to create mappers in java configuration, bean creation will be handled by framework.
#Mapping(target = "roles", expression = "java(appUser.getRoles().stream().map(this::getRoleName).collect(Collectors.toList()))")
now I get error that it cant find collectors
You are using an expression with Collectors class. As stated in the documentation https://mapstruct.org/documentation/stable/reference/html/#expressions:
Please note that the fully qualified package name is specified because MapStruct does not take care of the import of the TimeAndFormat class (unless it’s used otherwise explicitly in the SourceTargetMapper). This can be resolved by defining imports on the #Mapper annotation.
So you either need to fully qualify java.util.stream.Collectors in your expression or set "imports" parameter in #Mapper annotation: #Mapper(imports = Collectors.class).
I would also say, you could just write a normal Java method for roles mapping and not be dealing with expressions. But that's up to your taste.
The file name of the service should be the interface and its content the implementation. You have named it by the implementation.

Spring Boot - Entity With Kotlin List<Enum> Not Booting

I have been helping my team upgrade our Maven/SpringBoot/Kotlin project from Spring-Boot 2.7.5 to Spring-Boot 3.0.0. However, an issue on startup is preventing us from progressing. This has not been an issue before Spring-Boot 3.0.0.
Upon booting the application, I receive the following stack trace:
org.springframework.context.ApplicationContextException: Unable to start web server
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: class sun.reflect.generics.reflectiveObjects.WildcardTypeImpl cannot be cast to class java.lang.reflect.ParameterizedType (sun.reflect.generics.reflectiveObjects.WildcardTypeImpl and java.lang.reflect.ParameterizedType are in module java.base of loader 'bootstrap')
After spending a day checking configurations and isolating the problem, we were left with one entity in our application, where we were still having the issue. We then started removing fields from the entity, until the application was able to run. The field we removed was a kotlin.collections.List of type Interaction, an enum class that we had defined for the application.
In order to ensure privacy, here is an isolated slice of the application MVC that will replicate this issue:
package com.example.adminapp.adminauth.persistence
import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.persistence.*
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
#Entity
#Table(name = "a_test_entity")
class AdminTestEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null
var name: String? = null
#Column
#Convert(converter = StrListConverter::class)
var interactions: List<Interaction> = emptyList()
}
enum class Interaction { HI, BYE }
class StrListConverter : AttributeConverter<List<Interaction>, String?> {
override fun convertToDatabaseColumn(p0: List<Interaction>): String? = ObjectMapper().writeValueAsString(p0)
override fun convertToEntityAttribute(p0: String?): List<Interaction> =
p0?.let { listOf(*ObjectMapper().readValue(it, Array<Interaction>::class.java)) } ?: emptyList()
}
#Repository
interface AdminTestEntityRepository : CrudRepository<AdminTestEntity, Int?>
#RestController
#RequestMapping("/api/v1/admin/test")
class AdminTestController(private val adminTestEntityRepository: AdminTestEntityRepository) {
#GetMapping("all")
fun getAllTest() = adminTestEntityRepository.findAll()
}
The kicker for this whole issue is that it only seems to be List<Enum> that causes this issue. For example, the following three re-definitions do not cause an instance of this issue:
var interactions: ArrayList<Interaction> = emptyList()
var interactions: List<String> = emptyList()
var interactions: List<DataClass> = emptyList()
What could be the cause of this? Why is it only List<Enum>?
It seems that https://hibernate.atlassian.net/browse/HHH-15624 fixed this issue.

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.

Type mismatch: inferred type is () -> JoinColumn but JoinColumn was expected

We are using Corda 4, Springboot web server and Postgresql 11.
Following are the versions of Corda platform, Springboot server, and other essential dependencies used-
cordaReleaseGroup=net.corda
cordaVersion=4.0
gradlePluginsVersion=4.0.45
kotlinVersion=1.2.71
junitVersion=4.12
quasarVersion=0.7.10
spring_version = '4.3.11.RELEASE'
spring_boot_version = '2.0.2.RELEASE'
spring_boot_gradle_plugin_version = '2.1.1.RELEASE'
jvmTarget = "1.8"
log4jVersion =2.11.2
platformVersion=4
slf4jVersion=1.7.25
nettyVersion=4.1.22.Final
We were able to achieve the sending of single transaction record to a target vault table, from a node to another.
We have come across a requirement in which the transaction is of One-to-many type, for which parent-child tables need to be created in the vault.
Following is the code to create the schema for the parent-child tables but it throws error on compilation -
"Type mismatch: inferred type is () -> JoinColumn but JoinColumn was expected".
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
import java.util.UUID
object Schema1
object SchemaV1 : MappedSchema(
schemaFamily = Schema1.javaClass,
version = 1,
mappedTypes = listOf(PersistentEmployees::class.java,PersistentEmployeeVehicles::class.java))
{
#Entity
#Table(name = "TBL_EMPLOYEES")
class PersistentEmployees(
#Column(name = "EmployeeId")
var Pid: Long,
#Column(name = "EmployeeName")
var EmployeeName: String,
#Column(name = "EmployeeAddress")
var EmployeeAddress: String,
#OneToMany(cascade = [(CascadeType.PERSIST)])
#JoinColumns({
JoinColumn(name = "output_index", referencedColumnName = "output_index");
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id") })
private val EmpVehicles:List<PersistentEmployeeVehicles>
) : PersistentState(), Serializable
#Entity
#Table(name = "TBL_EMPLOYEE_VEHICLES")
class PersistentEmployeeVehicles(
#Column(name = "ID")
var ID: UUID,
#Column(name = "VEHICLETYPE")
var VEHICLETYPE: String,
#Column(name = "VEHICLEMODEL")
var VEHICLEMODEL: String,
#Column(name = "VEHICLENUMBER")
var VEHICLENUMBER: String
)
}
Question 1: What would be the cause of the error and also the solution (if possible)?
We used "Car insurance" "One-to-many" mapping sample from Corda Git Hub. Following are the links-
"https://github.com/corda/samples/blob/release-V4/carinsurance-QueryableState/contracts/src/main/java/net/corda/examples/carinsurance/schema/PersistentInsurance.java"
"https://github.com/corda/samples/blob/release-V4/carinsurance-QueryableState/contracts/src/main/java/net/corda/examples/carinsurance/schema/PersistentClaim.java"
The syntax for declaring arrays within annotations is different between Java and Kotlin, for Kotlin, you should use [] like the following:
#JoinColumns(value = [
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id") ])
private val EmpVehicles:List<PersistentEmployeeVehicles>

#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";
}

Resources