Spring Boot JPA - Projection selecting all fields from table when has a collection - spring

I trying to get two fields and a #ElementCollection from entity using projection with interface, but the JPA are selecting all fields from my entity and when i remove the method that get the list of my #ElementCollection the JPA select the only two fields.
My entity class:
#Entity(name = "users")
data class User(
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
#Column(nullable = false)
var name: String? = null,
#Column(unique = true, nullable = false)
var cpf: String? = null,
#Column(name = "phone_number", nullable = false)
var phoneNumber: String? = null,
#Column(unique = true, nullable = false)
var email: String? = null,
#Column(name = "password_hash")
var passwordHash: String? = null,
#Column(name = "password_hash_recovery")
var passwordHashRecovery: String? = null,
#Column(name = "password_hash_recovery_date")
var passwordHashRecoveryDate: String? = null,
#Column(name = "self_employed", nullable = false)
var selfEmployed: Boolean? = null,
#JoinColumn(name = "user_photo", referencedColumnName = "id")
#OneToOne(fetch = FetchType.LAZY)
var userPhoto: File? = null,
#JoinColumn(name = "id_location", referencedColumnName = "id")
#OneToOne(fetch = FetchType.LAZY)
var location: Location? = null,
#Column(name = "rating_star", nullable = false)
#Enumerated(EnumType.STRING)
var ratingStar: RatingStar = RatingStar.ONE,
#JoinColumn(name = "id_area", referencedColumnName = "id")
#OneToOne(fetch = FetchType.LAZY)
var area: Area? = null,
#OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var workTimes: List<WorkTime> = arrayListOf(),
#OneToMany(mappedBy = "contractor", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var contractorOrders: List<Order>? = arrayListOf(),
#OneToMany(mappedBy = "selfEmployed", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var selfEmployedOrders: List<Order>? = arrayListOf(),
) {
#ElementCollection(fetch = FetchType.EAGER)
#Enumerated(EnumType.STRING)
#CollectionTable(
name = "profiles_authorties",
joinColumns = [JoinColumn(name = "user_id", referencedColumnName = "id")],
)
#Column(name = "authority")
private val _authorities: MutableSet<ProfileAuthorities> = HashSet()
init {
_authorities.add(ProfileAuthorities.CLIENT)
}
fun setAsAdmin() =
_authorities.add(ProfileAuthorities.ADMIN)
fun getAuthorities(): Set<ProfileAuthorities> = _authorities
}
My interface for projection:
interface LoginUserProjection {
fun getId(): Long
fun getPasswordHash(): String
fun getAuthorities(): Set<ProfileAuthorities>
}
The result query is:
Hibernate: select user0_.id as id1_12_, user0_.id_area as id_area11_12_, user0_.cpf as cpf2_12_, user0_.email as email3_12_, user0_.id_location as id_loca12_12_, user0_.name as name4_12_, user0_.password_hash as password5_12_, user0_.password_hash_recovery as password6_12_, user0_.password_hash_recovery_date as password7_12_, user0_.phone_number as phone_nu8_12_, user0_.rating_star as rating_s9_12_, user0_.self_employed as self_em10_12_, user0_.user_photo as user_ph13_12_ from users user0_ where user0_.id=?
Hibernate: select authoriti0_.user_id as user_id1_8_0_, authoriti0_.authority as authorit2_8_0_ from profiles_authorties authoriti0_ where authoriti0_.user_id=?
when i remove fun getAuthorities(): Set<ProfileAuthorities> from LoginUserProjection the result is:
Hibernate: select user0_.id as col_0_0_, user0_.password_hash as col_1_0_ from users user0_ where user0_.id=?
My repository method:
#Repository
interface UserRepository : JpaRepository<User, Long> {
fun <T> getUserProjectionById(id: Long, projection: Class<T>): T?
}

Related

Kotlin spring JPA. lateinit property has not been initialized exception from getting lazy field of JPA entity

I use Spring Boot, Hibernate, Kotlin
In build.gradle.kts:
apply(plugin="org.hibernate.orm")
tasks.withType<org.hibernate.orm.tooling.gradle.EnhanceTask>().configureEach {
options.enableLazyInitialization = true
options.enableDirtyTracking = true
options.enableAssociationManagement = true
}
User entity:
#Entity
#Table(name = "user")
class User(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
var id: Long = -1,
#Column(name = "user_name", unique = true, nullable = false, length = 20)
var userName: String = "",
#Column(unique = true, nullable = false)
var email: String = "",
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "user_roles", joinColumns = [JoinColumn(name = "user_id")],
inverseJoinColumns = [JoinColumn(name = "role_id")])
var roles: MutableSet<Role> = mutableSetOf()
) {
#OneToOne(fetch = FetchType.LAZY, cascade = [CascadeType.ALL], mappedBy = "user", optional = false)
#LazyToOne(LazyToOneOption.PROXY)
#LazyGroup( "person" )
lateinit var person: Person
....
}
I get it by:
#Transactional
#Component
class UserServiceImpl (private val userRepository: UserRepository){
override fun getUserData(id: Long): Optional<UserView> {
return userRepository.findById(id).map { UserView.build(it, it.person) }
}
...
}
And it.person throws lateinit property has not been initialized exception, but Person was loaded( I see it by hibernate log ). Getting roles works fine.
I have same result without #LazyToOne(LazyToOneOption.PROXY) and #LazyGroup( "person" ).
SOLVED:
#OneToOne(fetch = FetchType.LAZY, cascade = [CascadeType.ALL])
#JoinColumn(name = "person_id", referencedColumnName = "id")
#LazyToOne(LazyToOneOption.PROXY)
#LazyGroup( "person" )
lateinit var person: Person

Why hibernate is throwing constraintViolationException?

Order Entity
#Entity
#Table(name = "Order",
indexes = {
#Index(name = "ORDER_X1", columnList = "REFERENCE_ID,SOURCE_ID"),
#Index(name = "ORDER_X2", columnList = "TYPE,STATUS")
}
)
#DiscriminatorColumn(name="PROCESSOR_TYPE", discriminatorType=DiscriminatorType.STRING, length = 80)
#SequenceGenerator(name="orderSeq", sequenceName="ORDER_SEQ")
#Inheritance(strategy= InheritanceType.JOINED)
public abstract class OrderEntity implements Serializable {
#Id
#GeneratedValue(strategy= GenerationType.SEQUENCE, generator="orderSeq")
private Long id;
#ManyToMany(cascade={CascadeType.MERGE})
#JoinTable(
name = "FILE_ORDER_MAP",
joinColumns = {#JoinColumn(name = "ORDER_ID")},
inverseJoinColumns = {#JoinColumn(name = "FILE_ID")}
)
private Set<TransferFile> transferFiles = new HashSet<>();
#Column(name = "TYPE")
#Enumerated(EnumType.STRING)
private OrderType type;
#Column(name = "AMOUNT", precision = 12, scale = 2)
private LcMoney amount;
#Column(name = "STATUS")
#Enumerated(EnumType.STRING)
private OrderStatus reconStatus;
#Type(type = LcUtc.JPA_JODA_TIME_TYPE)
#Column(name = "STATUS_D", nullable = false)
#LcDateTimeUtc()
private DateTime reconStatusDate;
#Column(name = "REFERENCE_ID")
private Long referenceId;
#Column(name = "SOURCE_ID")
private Long sourceId;
#Column(name = "ACCOUNT_ID")
private Long accountId;
#Column(name = "PROCESSOR_TYPE", insertable = false, updatable = false)
#Enumerated(EnumType.STRING)
private OrderProcessorType processorType;
#Type(type = LcUtc.JPA_JODA_TIME_TYPE)
#Column(name = "TX_EXECUTION_D")
#LcDateTimeUtc()
private DateTime executedDate;
#Type(type = LcUtc.JPA_JODA_TIME_TYPE)
#Column(name = "CREATE_D")
#LcDateTimeUtc()
private DateTime createDate;
#Column(name = "IS_ON_DEMAND")
#Type(type = "yes_no")
private boolean isOnDemand;
#ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = {CascadeType.PERSIST})
#JoinColumn(name="PAYER_ID", nullable=true)
private Payer payer;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "ORDER_ID", referencedColumnName = "ID")
private List<OrderTransaction> orderTransactions;
#OneToMany(cascade = {CascadeType.ALL})
#JoinColumn(name = "ORDER_ID", referencedColumnName = "ID",
foreignKey = #ForeignKey(name = "FK_ORDER")
)
private List<MatchResult> matchResults;
#Version
#Column(name = "VERSION")
private Integer version;
#Embedded
#AttributeOverrides({
#AttributeOverride(name = "externalSourceId", column = #Column(name = "TRANS_EXT_SRC_ID")),
#AttributeOverride(name = "externalId", column = #Column(name = "TRANS_EXT_REF_ID"))
})
private LcExternalIdEntity transExtId;
#PreUpdate
#PrePersist
public void beforePersist() {
if (reconStatusDate != null) {
reconStatusDate = reconStatusDate.withZone(DateTimeZone.UTC);
}
if (executedDate != null) {
executedDate = executedDate.withZone(DateTimeZone.UTC);
}
if (createDate != null) {
createDate = createDate.withZone(DateTimeZone.UTC);
}
}
// getters and setters
}
//controller method
public Response processFile(){
// separate trasaction
service.readFileAndCreateOrders(); // read files and create orders in new status
List<Order> newOrders = service.getNewOrders();
for( Order order: newOrders){
service.processOrder(order); // separate transaction
}
}
#Transaction
void processOrder(OrderEntity order){
matchResultJpaRepository.save(orderEntity.id);
log.info("Saving matchId={} for order={}", match.getId(), order.getId());
// create new transaction and add to order
OrderTransaction transaction = createNewTransaction(order);
order.getTransactions().add(transaction);
order.setStatus("PROCESSED");
log.info("Saving Order id={}, Type={}, Status={} ", order.getId(), order.getType(), order.getStatus());
orderRepository.save(order);
}
I am seeing this below error.
ORA-01407: cannot update ("PAYMENTS"."MATCH_RESULT"."ORDER_ID") to NULL
This endpoing is not exposed to user. There is a batch job which invokes this endpoint.
This code has been there for atleast a year and this is the first time i am seeing this.
This happened only once and for only one call. I am seeing both the logs printed. I am puzzled why I am seeing above error complaining about NULL order id. From the logs, we can confirm that the order id is definitely not null.
Any idea why this is happening? What can be done to fix this?

Hibernate model with multiple many-to-many relations slow performance when persisting

We have following schema as described on diagram below. There's an Entity with bidirectional many-to-many relations with two other entities(Relation1, Relation2). There's also many-to-many relation between Entity-Relation2 relationship itself and Relation1 entity. When we create an instance of Entity and persist into database, it's working fine, except that operation takes too much time. I'd like to ask, if there are any possible optimizations on Hibernate level, which could boost performance of save operation.
Here's diagram:
Model definitions:
class Entity : AbstractJpaPersistable() {
var name: String? = null
var description: String? = null
#OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations1: List<EntityToRelation1> = emptyList()
#OneToMany(mappedBy = "entity", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations2: List<EntityToRelation2> = emptyList()
}
#Entity
class Relation2: AbstractJpaPersistable(){
#OneToMany(mappedBy = "relation2", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations2: List<EntityToRelation2> = emptyList()
}
#Entity
class Relation1: AbstractJpaPersistable(){
#OneToMany(mappedBy = "relation1", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations1: List<EntityToRelation1> = emptyList()
#OneToMany(mappedBy = "relation1", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations2Relations1: List<EntityToRelation2ToRelation1> = emptyList()
}
#Entity
class EntityToRelation2 {
#EmbeddedId
var entityToRelation2Id: EntityToRelation2Id = EntityToRelation2Id()
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("entityId")
#JoinColumn(name = "entity_id", insertable = false, updatable = false)
var entity: Entity? = null
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("relation2Id")
#JoinColumn(name = "relation2_id", insertable = false, updatable = false)
var relation2: Relation2? = null
#OneToMany(mappedBy = "entityToRelation2", fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST], orphanRemoval = true)
var entityRelations2Relations1: List<EntityToRelation2ToRelation1> = emptyList()
}
#Embeddable
class EntityToRelation2Id : Serializable {
#Column(name = "entity_id")
var entityId: Int? = null
#Column(name = "relation2_id")
var relationId: Int? = null
}
#Entity
class EntityToRelation1 {
#EmbeddedId
var entityToRelation1Id = EntityToRelation1Id()
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("entityId")
#JoinColumn(name = "entity_id", insertable = false, updatable = false)
var entity: Entity? = null
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("relation1Id")
#JoinColumn(name = "relation1_id", insertable = false, updatable = false)
var relation1: Relation1? = null
}
#Embeddable
class EntityToRelation1Id : Serializable {
#Column(name = "entity_id")
var entityId: Int? = null
#Column(name = "relation1_id")
var relation1Id: Int? = null
}
#Entity
class EntityToRelation2ToRelation1 {
#EmbeddedId
var entityToRelation2ToRelation1Id = EntityToRelation2ToRelation1Id()
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("entityToRelation2Id")
#JoinColumns(
JoinColumn(name = "entity_id"),
JoinColumn(name = "relation2_id")
)
var entityToRelation2: EntityToRelation2? = null
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("relation1Id")
#JoinColumn(name = "relation1_id", insertable = false, updatable = false)
var relation1: Relation1? = null
}
#Embeddable
class EntityToRelation2ToRelation1Id : Serializable {
var entityToRelation2Id: EntityToRelation2Id? = null
#Column(name = "relation1_id")
var relation1Id: Int? = null
}

Spring Data JPA Pageable with named entity graph

I am using Spring data with JPA 2.1 to retrieve the entities with pagination & specification (criteria builder) using below method:
Page<T> findAll(Specification<T> spec, Pageable pageable)
How can i specify #EntityGraph on this method? Rightnow, if i annotate with #EntityGraph, Spring stops doing the pagination and fetch whole data in one go.
#EqualsAndHashCode(callSuper = true)
#Data
#Entity
#Table(name = "cd_order")
#Where(clause = "deleted = " + UN_DELETED)
#NamedEntityGraphs(value = {
#NamedEntityGraph(name = "findAll", attributeNodes =
{#NamedAttributeNode(value = "company"),
#NamedAttributeNode(value = "partnerCompany"),
// remove one to many , #NamedAttributeNode(value = "orderOssUrls"),
#NamedAttributeNode(value = "patient")
})}
)
public class Order extends BaseEntity {
#Column(name = "patient_id", insertable = false, updatable = false, columnDefinition = " BIGINT NOT NULL COMMENT '订单id' ")
private Long patientId;
#OneToOne(fetch = FetchType.EAGER)
#Fetch(FetchMode.JOIN)
#NotFound(action = NotFoundAction.IGNORE)
#JoinColumn(foreignKey = #ForeignKey(ConstraintMode.NO_CONSTRAINT), name = "patient_id", referencedColumnName = "id")
private Patient patient;
#Column(name = "patient_name", columnDefinition = " VARCHAR(48) COMMENT '案例编号' ")
private String patientName;
#Column(name = "case_code", columnDefinition = " VARCHAR(48) NOT NULL COMMENT '案例编号' ")
private String caseCode;
#Column(name = "company_id", insertable = false, updatable = false, columnDefinition = " BIGINT COMMENT 'companyId' ")
private Long companyId;
#OneToOne(fetch = FetchType.EAGER)
#Fetch(FetchMode.JOIN)
#JoinColumn(foreignKey = #ForeignKey(ConstraintMode.NO_CONSTRAINT), name = "company_id", referencedColumnName = "id")
#NotFound(action = NotFoundAction.IGNORE)
private Company company;
#Column(name = "partner_company_id", insertable = false, updatable = false, columnDefinition = " BIGINT COMMENT '合作伙伴的companyId' ")
private Long partnerCompanyId;
#OneToOne(fetch = FetchType.EAGER)
#Fetch(FetchMode.JOIN)
#JoinColumn(foreignKey = #ForeignKey(ConstraintMode.NO_CONSTRAINT), name = "partner_company_id", referencedColumnName = "id")
#NotFound(action = NotFoundAction.IGNORE)
private Company partnerCompany;
#Column(name = "order_id", columnDefinition = " BIGINT NOT NULL COMMENT '订单id' ")
private Long orderId;
#Fetch(FetchMode.JOIN)
#NotFound(action = NotFoundAction.IGNORE)
#JoinColumn(foreignKey = #ForeignKey(ConstraintMode.NO_CONSTRAINT), name = "order_id", referencedColumnName = "order_id")
#OneToMany(fetch = FetchType.LAZY)
private List<OrderOssUrl> orderOssUrls;
#Column(name = "recovery_info", columnDefinition = " VARCHAR(128) COMMENT '恢复信息' ")
private String recoveryInfo;
/**
* 交货日期
*/
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
#Column(name = "submit_time", columnDefinition = " datetime COMMENT '请求交货日期' ")
private LocalDateTime submitTime;
/**
* 订购日期
*/
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
#Column(name = "order_time", columnDefinition = " datetime COMMENT '订购日期' ")
private LocalDateTime orderTime;
/**
* 扫描日期
*/
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
#Column(name = "scan_time", columnDefinition = " datetime COMMENT '扫描日期' ")
private LocalDateTime scanTime;
#Enumerated(value = EnumType.STRING)
#Column(name = "order_type", columnDefinition = " VARCHAR(20) NOT NULL COMMENT '订单类型' ")
private OrderTypeEnum orderType;
#Enumerated(value = EnumType.STRING)
#Column(name = "cc_order_status", columnDefinition = " VARCHAR(20) COMMENT '诊所订单状态' ")
private OrderStatusEnum ccOrderStatus;
#Enumerated(value = EnumType.STRING)
#Column(name = "lab_order_status", columnDefinition = " VARCHAR(20) COMMENT '工厂订单状态' ")
private OrderStatusEnum labOrderStatus;
/**
* #param orderType 订单类型
*/
public void init(#NonNull OrderTypeEnum orderType) {
generateCaseCode();
if (orderType == OrderTypeEnum.CLINIC) {
this.setCcOrderStatus(OrderStatusEnum.NEW);
} else {
this.setLabOrderStatus(OrderStatusEnum.NEW);
}
this.setOrderType(orderType);
this.setOrderId(GlobalUniqueIdGeneratorUtils.generateOrderId());
}
/**
* 设置案例编号
*/
private void generateCaseCode() {
this.setCaseCode(getYMDStrCurrently() + "-" + this.getPatient().getName());
}
}
public interface OrderRepository extends BaseRepository<Order, Long> {
#NonNull
#EntityGraph(value = "findAll", type = EntityGraph.EntityGraphType.LOAD)
Page<Order> findAll(Specification<Order> specification, #NonNull Pageable pageable);
}
sql
select order0_.id as id1_5_0_,
patient1_.id as id1_9_1_,
company2_.id as id1_1_2_,
company3_.id as id1_1_3_,
order0_.create_time as create_t2_5_0_,
order0_.deleted as deleted3_5_0_,
order0_.update_time as update_t4_5_0_,
order0_.version as version5_5_0_,
order0_.case_code as case_cod6_5_0_,
order0_.cc_order_status as cc_order7_5_0_,
order0_.company_id as company_8_5_0_,
order0_.lab_order_status as lab_orde9_5_0_,
order0_.order_id as order_i10_5_0_,
order0_.order_time as order_t11_5_0_,
order0_.order_type as order_t12_5_0_,
order0_.partner_company_id as partner13_5_0_,
order0_.patient_id as patient14_5_0_,
order0_.patient_name as patient15_5_0_,
order0_.recovery_info as recover16_5_0_,
order0_.scan_time as scan_ti17_5_0_,
order0_.submit_time as submit_18_5_0_,
patient1_.create_time as create_t2_9_1_,
patient1_.deleted as deleted3_9_1_,
patient1_.update_time as update_t4_9_1_,
patient1_.version as version5_9_1_,
patient1_.activity_time as activity6_9_1_,
patient1_.day as day7_9_1_,
patient1_.email as email8_9_1_,
patient1_.month as month9_9_1_,
patient1_.name as name10_9_1_,
patient1_.note as note11_9_1_,
patient1_.phone as phone12_9_1_,
patient1_.sex as sex13_9_1_,
patient1_.year as year14_9_1_,
company2_.create_time as create_t2_1_2_,
company2_.deleted as deleted3_1_2_,
company2_.update_time as update_t4_1_2_,
company2_.version as version5_1_2_,
company2_.additional_info_id as addition6_1_2_,
company2_.address as address7_1_2_,
company2_.biz_type as biz_type8_1_2_,
company2_.cell_phone as cell_pho9_1_2_,
company2_.city as city10_1_2_,
company2_.country_code as country11_1_2_,
company2_.country_name as country12_1_2_,
company2_.description as descrip13_1_2_,
company2_.icon as icon14_1_2_,
company2_.language as languag15_1_2_,
company2_.mechanism_id as mechani16_1_2_,
company2_.name as name17_1_2_,
company2_.office_phone as office_18_1_2_,
company2_.postcode as postcod19_1_2_,
company2_.province as provinc20_1_2_,
company2_.time_zone as time_zo21_1_2_,
company3_.create_time as create_t2_1_3_,
company3_.deleted as deleted3_1_3_,
company3_.update_time as update_t4_1_3_,
company3_.version as version5_1_3_,
company3_.additional_info_id as addition6_1_3_,
company3_.address as address7_1_3_,
company3_.biz_type as biz_type8_1_3_,
company3_.cell_phone as cell_pho9_1_3_,
company3_.city as city10_1_3_,
company3_.country_code as country11_1_3_,
company3_.country_name as country12_1_3_,
company3_.description as descrip13_1_3_,
company3_.icon as icon14_1_3_,
company3_.language as languag15_1_3_,
company3_.mechanism_id as mechani16_1_3_,
company3_.name as name17_1_3_,
company3_.office_phone as office_18_1_3_,
company3_.postcode as postcod19_1_3_,
company3_.province as provinc20_1_3_,
company3_.time_zone as time_zo21_1_3_
from cd_order order0_
left outer join cd_patient patient1_ on order0_.patient_id = patient1_.id
left outer join cd_company company2_ on order0_.partner_company_id = company2_.id
left outer join cd_company company3_ on order0_.company_id = company3_.id
where (order0_.deleted = 0)
and order0_.order_id >= 1
and (order0_.case_code like '%case%')
and patient1_.year >= 1
and patient1_.month >= 1
and patient1_.day >= 1
and patient1_.sex = 'MALE'
and (patient1_.phone like '%phone%')
and (patient1_.name like '%name%')
and (order0_.update_time between '2021-06-23 14:40:53.101831' and '2021-06-27 14:40:53.101944')
order by order0_.create_time asc, order0_.submit_time desc
limit 10
please remove #NamedAttributeNode of on to many enter image description here,and try debug org.hibernate.hql.internal.ast.QueryTranslatorImplenter image description here
。 please care RowSelection。 i fixed the 'bug'

Spring Security, Refresh Token & NotSerializableException

I have the following entities:
#Entity
#Table(name = "ct_users")
#JsonIgnoreProperties("password", "enabled", "driver", "reviews")
open class User(
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Int = 0,
#Column
val phone: String = "",
#Column
val password: String = "",
#Column
val enabled: Boolean = false,
#OneToOne(fetch = FetchType.LAZY, mappedBy="profile")
var driver: Driver? = null,
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(
name = "ct_reviews_rel",
joinColumns = arrayOf(JoinColumn(name = "user_id")),
inverseJoinColumns = arrayOf(JoinColumn(name = "review_id"))
)
#JsonManagedReference
var reviews: List<Review>? = null
) : Serializable
And related drivers table:
#Entity
#Table(name = "ct_drivers")
#JsonIgnoreProperties("password", "profile")
class Driver(
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int = 0,
#Column(name = "first_name")
var firstName: String = "",
#Column(name = "last_name")
var lastName: String = "",
#Column(name = "rating")
var rating: Double = 5.0,
#Column(name = "reviews")
var reviewsCount: Int = 0,
#Column(name = "invited_by")
var invitedBy: Int? = 0,
#Column(name = "position_prev", columnDefinition = "geometry(Point,4326)")
var positionPrev: Point = Helpers.geometry(0.0, 0.0),
#Column(columnDefinition = "geometry(Point,4326)")
var position: Point = Helpers.geometry(0.0, 0.0),
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
var profile: User? = null,
#Transient
var distance: Int = 0
) : Serializable
When i try to refresh token (/oauth/token?grant_type=refresh_token&client_id=abc&client_secret=abcd&refresh_token=...), i got the following error message:
{
"error": "server_error",
"error_description": "java.io.NotSerializableException: org.geolatte.geom.jts.PointSequenceCoordinateSequenceFactory"
}
How can i fix it? And what is the cause of this problem?
Helpers.geometry func:
fun geometry(lat: Double, lng: Double): Point {
return GeometryFactory(PrecisionModel(), 4326).createPoint(Coordinate(lat, lng))
}
My fault. Problem was in my UserDetailsService,

Resources