Request processing failed; nested exception is java.lang.ClassCastException: Cannot cast java.lang.String to java.time.LocalDateTime] with root cause - spring

I am using Java 1.8 & SpringBoot 2.3.4.RELEASE. I am trying to use the AuditingEntityListener and #MappedSuperclass features to populate the created_date and updated_date timestamps.
But I am getting this Exception: java.lang.ClassCastException: Cannot cast java.lang.String to java.time.LocalDateTime
I tried without #MappedSuperclass and it works.....but the created_date and updated_date fields are not getting populated.
Can anyone help me on this?
Here is the code snippet:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity implements Serializable {
#CreatedDate
#Column(name = "created_ts",nullable = false, updatable = false)
private LocalDateTime createdDate;
#LastModifiedBy
#Column(name = "updated_ts",nullable = false)
private LocalDateTime updatedDate;
#CreatedBy
#Column(name = "src_sys_cd",length = 15, updatable = false)
private String source;
#Version
#Column(name = "record_version_nb", length = 20, nullable = false)
private Long version;
}
----------------------------------
#Component
public class AuditorAwareImpl implements AuditorAware<String> {
#Value("${customer.service.source.code}")
private String auditor;
#Override
public Optional<String> getCurrentAuditor() {
return Optional.of(auditor);
}
}
----------------------------------
#Entity
#Setter
#Getter
#Builder
#Table(name = "customer_information")
#AllArgsConstructor
#NoArgsConstructor
public class CustomerEntity extends AuditableEntity {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
}

#LastModifiedBy is used to set the current user when a modification happens. That is typically a String which can't be converted to anything date/time like and doesn't seem to be what you were looking for.
You should change this to:
#LastModifiedBy
#Column(name = "updated_ts",nullable = false)
private LocalDateTime updatedDate;
#LastModifiedDate
#Column(name = "updated_ts",nullable = false)
private LocalDateTime updatedDate;

Related

Jpa Inheritance showing me the superclass fields

My super-class is annotated with #Inheritance(strategy = InheritanceType.SINGLE_TABLE) and my sub-class is inheriting from it, that means when i try to get data in Postman it retrieve also the superclass fields which I don't that to happen, any help please
#Table(name = "SUPER_CLASS-TABLE")
#Entity
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor(force = true)
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class SUPERCLASSTABLE implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, updatable = false)
private Long tblId;
#CreatedDate
#CreationTimestamp
private Date publishingDate;
private String name;
}
#Getter
#Setter
#Entity
#AllArgsConstructor
#NoArgsConstructor
#DiscriminatorValue("sub-class")
public class SUBCLASSTABLE extends SUPERCLASSTABLE {
private String cin;
private String firstNname;
private String lastName;
#OneToOne(cascade = CascadeType.ALL, optional = false)
#JsonIgnore
private SUPERCLASSTABLE superclasstable;
This is my response request:
{
"tblId": 1,
"publishingDate" : "2022-03-13",
"name" : "SomeName"
"sub-classtable"{
"tblId": null,
"publishingDate" : null,
"name" : null
"cin": "somedata",
"firstName": "somedata",
"lastName": "somedata"
}
}
So what I want is just the data of subclass

Spring Data JPA separate createOn and updateOn

my auditing works pretty nice but need to change create listener in that way to obtain null values in first update.
#MappedSuperclass
#Getter
#Setter
#ToString
#EntityListeners(AuditingEntityListener.class)
public abstract class AbstractEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Version
private int version;
#CreatedBy
private String createdBy;
#LastModifiedBy
private String updatedBy;
#CreatedDate
private LocalDateTime createdAt;
#LastModifiedDate
private LocalDateTime updatedAt;
}
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#ToString
public class TestProfile extends AbstractEntity{
private String username;
}
Right now during create entity, the "updatedBy" and "updatedAt" is also fullfilled with duplicated values from "createdBy" and "createdAt". Should I change my default implementation to #PrePersist and #PreUpdate?
Here is my JpaConfig
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class AuditingConfig`enter code here` {
#Bean
public AuditorAware<String> auditorAware() {
return () -> Optional.of(((UserDetails) SecurityContextHolder
.getContext().getAuthentication().getPrincipal()).getUsername());
}
}

Embed complex object in entity

I want to embed the following
#Embeddable
public class BaseEntity implements Serializable {
#Id
#GeneratedValue
private UUID id;
#CreatedDate
#Column(name = "created_date", updatable = false)
private LocalDateTime createdDate;
}
into my room entity
#Entity
#Data
#NoArgsConstructor
#Table(name = "room")
public class room {
#EmbeddedId
private BaseEntity baseEntity;
#Column(length = 80, nullable = false)
private String name;
}
So that my generated table looks like this
room
id
createdDate
name
But id and createdDate are not getting embedded
Instead of #Embeddable just extend your BaseEntity
#MappedSuperclass
#Getter
#Setter
public class BaseEntity implements Serializable {
#Id
#GeneratedValue
private UUID id;
#CreatedDate
#Column(name = "created_date", updatable = false)
private LocalDateTime createdDate;
}
#Entity
#Data
#NoArgsConstructor
#Table(name = "room")
public class room extends BaseEntity{
#Column(length = 80, nullable = false)
private String name;
}

Auto populate created_date, last_modified_date, created_by and last_modified_by in entity : Hibernate with JPA

I am new to Hibernate and JPA. I have several entities, each of which contains following four columns:
1. created_by
2. last_modified_by
3. created_date
4. last_modified_date
I would like these columns to get auto-populated while saving the associated entity.
Two sample entities are as follows:
Entity 1:
#Entity
#Table(name = "my_entity1")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class MyEntity1 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private String lastModifiedDate;
}
Entity 2:
#Entity
#Table(name = "my_entity2")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class MyEntity2 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "description")
private String description;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private String lastModifiedDate;
}
In this context, I have gone through following posts: How to autogenerate created or modified timestamp field?, How can you make a created_at column generate the creation date-time automatically like an ID automatically gets created?.
I am getting how to capture the dates fields but I cannot understand how to capture created_by and last_modified_by.
Auditing Author using AuditorAware and Spring Security...
To tell JPA about currently logged in user we will need to provide an
implementation of AuditorAware and override getCurrentAuditor()
method. And inside getCurrentAuditor() we will need to fetch currently
logged in user.
Like this:
public class AuditorAwareImpl implements AuditorAware<String> {
#Override
public String getCurrentAuditor() {
return "TestUser";
// Can use Spring Security to return currently logged in user
// return ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername()
}
}
Now enable jpa auditing by using #EnableJpaAuditing
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorAware")
public class JpaConfig {
#Bean
public AuditorAware<String> auditorAware() {
return new AuditorAwareImpl();
}
}
Look at this to get more details....

How to get an Authenticated User's Details in Spring Security OAuth2

I am unable to extract the current logged in user in Spring Security OAuth2. My goal is to extract the user when the create event on ClientSuggestion entity is triggered and persist it to the database.
Employee.java
#Entity
#Table(name = "er_employee")
public class Employee implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "username", unique = true)
#NotNull
#Size(max = 10)
private String username;
#Column(name = "password_hash")
#NotNull
#Size(min = 8, max = 512)
private String password;
#Column(name = "email_verification_token")
#Size(max = 512)
private String emailVerificationToken;
#Column(name = "password_reset_token")
#Size(max = 512)
private String passwordResetToken;
#Column(name = "active")
#NotNull
private boolean active;
#Column(name = "is_deleted")
#NotNull
private boolean deleted;
#Column(name = "date_of_creation")
#Temporal(TemporalType.TIMESTAMP)
#NotNull
private Date dateOfCreation;
#OneToMany(mappedBy = "employee")
private List<ClientSuggestion> clientSuggestions;
//Constructors
//Getters ans setters
}
ClientSuggestion.java
#Entity
#Table(name = "er_suggestion")
public class ClientSuggestion implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "content", unique = true)
#NotNull
#Size(max = 200)
private String suggestion;
#ManyToOne
#JoinColumn(name = "employee_id")
private Employee employee;
//Constructors
//Getters ans setters
}
EmployeeRepository.java
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
ClientSuggestionRepository .java
public interface ClientSuggestionRepository extends CrudRepository<ClientSuggestion, Long> {
}
The event handler
#Component
#RepositoryEventHandler(ClientSuggestion.class)
public class ClientSuggestionEventHandler {
Employee employee= (Employee ) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
#HandleBeforeCreate
public void handleClientSuggestionBeforeCreate(ClientSuggestion cs) {
cs.setDeleted(false);
cs.setActive(true);
cs.setPasswordResetToken(Encryptor.generateHash(cs.getPassword, 512));
cs.setEmployee(employee);
}
}
The bean, ClientSuggestionEventHandler, is registered in a configuration class. When I tried running the project, NullPointerException exception is thrown. I wish to find out how to get the current logged employee.
I'm new to Spring Security OAuth2. Thanks.
In Employee.java implement org.springframework.security.core.userdetails.UserDetails class
Employee.java
#Entity
#Table(name = "er_employee")
public class Employee implements Serializable, UserDetails {
And then use Employee employee= (Employee) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

Resources