No property found SpringBoot JPA - spring-boot

I encouter this error while running the app, i dont understand why.. i found information on the web, but can't understand what's wrong. Thanks for help.
2 ) Another question regarding this, should i put :
List<HistoriqueDeploiement> findByIdNamespaceAndIdService(Namespace id_namespace, Service id_service);
Or
List<HistoriqueDeploiement> findByIdNamespaceAndIdService(Integer id_namespace, Integer id_service);
The error :
Error creating bean with name 'checkConfigDeploiementRepository': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.example.jpa.repository.CheckConfigDeploiementRepository.findByIdNamespaceAndIdService(com.example.jpa.model.Namespace,com.example.jpa.model.Service)! No property namespace found for type Integer! Traversed path: CheckConfigDeploiement.id.
The Entity :
#Entity
#Table(name = "historiquedeploiement")
#Data
#EqualsAndHashCode(callSuper=false)
#NoArgsConstructor
#AllArgsConstructor
public class HistoriqueDeploiement extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id", nullable=false, unique=true)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "id_namespace", nullable = false)
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
#JsonIdentityReference(alwaysAsId=true)
#JsonProperty("id_namespace")
private Namespace namespace;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "id_service", nullable = false)
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
#JsonIdentityReference(alwaysAsId=true)
#JsonProperty("id_service")
private Service service;
#NotEmpty(message = "Le GitCommit ne peut être vide")
#Size(max = 255)
private String gitCommit;
#NotEmpty(message = "Le TagVersion ne peut être vide")
#Size(max = 100)
private String tagVersion;
#NotEmpty(message = "Le Actionby ne peut être vide")
#Size(max = 255)
private String actionBy;
}
NamespaceEntity ( same with service..)
#Entity
#Table(name = "namespace")
#Data
#EqualsAndHashCode(callSuper=false)
#NoArgsConstructor
#AllArgsConstructor
public class Namespace extends AuditModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id", nullable=false, unique=true)
private Integer id;
#NotEmpty
#Size(max = 100)
#Column(unique = true)
private String namespace;
#OneToMany(mappedBy = "namespace", cascade = CascadeType.ALL, orphanRemoval = true)
private List<HistoriqueDeploiement> historiquedeploiements = new ArrayList<>();
public void addHistoriqueDeploiement(HistoriqueDeploiement historiquedeploiement) {
historiquedeploiements.add(historiquedeploiement);
historiquedeploiement.setNamespace(this);
}
public void removeHistoriqueDeploiement(HistoriqueDeploiement historiquedeploiement) {
historiquedeploiements.remove(historiquedeploiement);
historiquedeploiement.setNamespace(null);
}
}
The repo, i don't understand what i'm doing wrong :
...
#Repository
public interface HistoriqueDeploiementRepository extends JpaRepository<HistoriqueDeploiement, Integer> {
List<HistoriqueDeploiement> findAll();
List<HistoriqueDeploiement> findByIdNamespace(Integer id);
List<HistoriqueDeploiement> findByIdNamespaceAndIdService(Namespace id_namespace, Service id_service);
List<HistoriqueDeploiement> findByIdNamespaceAndLogCreatedAtBetween(Namespace id_namespace, Date datedebut, Date datefin);
List<HistoriqueDeploiement> findByIdNamespaceAndLogCreatedAt(Namespace id_namespace, Date date);
}

Okay so I looked at your problem and here is what I found. The types you assigned to your repository interface method parameters are wrong.
You are looking to obtain a list of HistoriqueDeploiement entities whose Namespace and Service entities have specific IDs. Note that IDs of Namespace and Service entities are Integer types. So in order to solve you can simply rewrite your methods as follows:
#Repository
public interface HistoriqueDeploiementRepository extends
JpaRepository<HistoriqueDeploiement, Integer> {
List<HistoriqueDeploiement> findAll();
List<HistoriqueDeploiement> findByNamespaceId(Integer id);
List<HistoriqueDeploiement> findByNamespaceIdAndServiceId(Integer id_namespace, Integer id_service);
List<HistoriqueDeploiement> findByNamespaceIdAndLogCreatedAtBetween(Integer id_namespace, Date datedebut, Date datefin);
List<HistoriqueDeploiement> findByNamespaceIdAndLogCreatedAt(Integer id_namespace, Date date);
}
Note that major change here is that we replaced Namespace and Service types with Integer type, which is the actual type of their IDs

Related

No converter found capable of converting from type [java.math.BigInteger] to Entity

I'm trying to get a list of transactions from database and this is the error I'm facing.
"trace": "org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object[]] to type [com.wallet.sendmoney.entities.TransactionEntity] for value '{1, 1, null, null, KES, null, 123456, LQALVZCFJMU6, null, 2547XXXXXX3, 61234, Load wallet, null, null, null, null, null, WS322, null}'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.math.BigInteger] to type [com.wallet.sendmoney.entities.TransactionEntity]
I'm using JPA #Query annotation and here is my repository
#Repository
public interface TransactionsRepository extends JpaRepository<LoadWalletEntity, Long> {
#Query(value = "SELECT * FROM transactions_attempts WHERE mobile_number= :mobile_number", nativeQuery = true)
List<TransactionEntity> getAllByPhoneNumber(#RequestParam String mobile_number);
}
Here is my entity class:
#Entity(name = "transactions_attempts")
#Table
#Data
#NoArgsConstructor
#AllArgsConstructor
public class LoadWalletEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String currency;
#Column(name = "mobile_number")
private String mobileNumber;
private String transactionRef;
private String merchantCode;
private Integer amount;
private String networkCode;
private String reason;
private String statusCode;
private String merchantReference;
private String merchantRequestId;
private String checkoutRequestId;
private Integer resultCode;
private String resultDescription;
private String billRefNumber;
private Date transactionDate;
#Column(name = "customer_mobile")
private String customerMobile;
private String thirdPartyTransId;
}
What could I be missing or doing wrong here.
Thanks in advance
you are trying to query a list of TransactionEntity
but your Repository is extends with
extends JpaRepository<LoadWalletEntity, Long> {
what's this LoadWalletEntity????
it should be
extends JpaRepository<TransactionEntity, Long> {
Try this solution please:
#Entity
#Table(name = "transactions_attempts")
instead of
#Entity(name = "transactions_attempts")
#Table

JpaRepository returning child for the first item in the list and then only the id for the rest

I have the following Post class:
#Entity
#Table(name = "posts")
#Getter
#Setter
#JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id",
scope = Long.class)
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String subtitle;
private String content;
private String img_url;
#CreationTimestamp
private Timestamp created_on;
#UpdateTimestamp
private Timestamp last_updated_on;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "owner_id", nullable=false)
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private User creator;
}
And the following repository that extends JpaRepository
#Repository
public interface PostRepository extends JpaRepository<Post, Long> {
Optional<Post> findById(Long id);
List<Post> findAll();
}
When returning the result of findAll() inside the following controller, only the first creator item is sent completely and the rest just contain the id:
#GetMapping("/news")
public List<Post> getNews() {
return postRepository.findAll();
}
This is the JSON I get as result:
[
{"id":15,"title":"Title example #1","subtitle":"Subtitle example #1","content":"Lorem #1 ipsum dolor sit amet","img_url":null,"created_on":"2021-12-01T00:00:00.000+00:00","last_updated_on":"2021-12-01T00:00:00.000+00:00","creator":{"id":1,"username":"user-example","email":"blablabla#gmail.com","roles":[{"id":1,"name":"ROLE_USER"}]}}
,{"id":25,"title":"Title example #2","subtitle":"Subtitle example #2","content":"Lorem #2 ipsum dolor sit amet","img_url":null,"created_on":"2021-12-01T00:00:00.000+00:00","last_updated_on":"2021-12-01T00:00:00.000+00:00","creator":1}
]
Why is this happening? Is there a way I can get the whole child object for every element in the JSON array?
Thanks
EDIT: added the User class
#Entity
#Table( name = "users",
uniqueConstraints = {
#UniqueConstraint(columnNames = "username"),
#UniqueConstraint(columnNames = "email")
})
#DiscriminatorValue(value="USER")
public class User extends OwnerEntity {
#NotBlank
#NotNull
#Size(max = 20)
private String username;
#NotBlank
#NotNull
#Size(max = 50)
#Email
private String email;
#NotBlank
#Size(max = 120)
#JsonIgnore
private String password;
#CreationTimestamp
private Timestamp created_on;
#UpdateTimestamp
private Timestamp last_updated_on;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable( name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
#ManyToMany(fetch = FetchType.LAZY)
private Set<Institution> institutions;
#OneToMany(mappedBy="creator", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
protected Set<Post> posts;
#ManyToMany(fetch = FetchType.LAZY)
private Set<Institution> following;
}
EDIT 2: Added the OwnerEntity class
#Entity
#Table(name = "entities")
#Inheritance(strategy = InheritanceType.JOINED)
#DiscriminatorColumn
#Getter
#Setter
#JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id",
scope = Long.class)
public class OwnerEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
}
Your OwnerEntity also has #JsonIdentityInfo. In its reference documentation we can read the following:
Annotation used for indicating that values of annotated type or
property should be serializing so that instances either contain
additional object identifier (in addition actual object properties),
or as a reference that consists of an object id that refers to a full
serialization. In practice this is done by serializing the first
instance as full object and object identity, and other references to
the object as reference values.
This perfectly explains why you are getting the JSON like that. If you don't want this, just remove #JsonIdentityInfo but it might be there to fix an infinite recursion while serializing bidirectional relationships (you can read more about this in the following online resource https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion).

OneToOne CascadeType in spring data jpa

I use OneToOne in the spring data JPA and I want to delete a record from the Address table without touching the user. But I can't.
If I remove User, in this case Address is removed, that's good.
But how can you delete an Address without touching the User?
https://github.com/myTestPercon/TestCascade
User.Java
#Entity
#Table(name = "user", schema = "testCascade")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
private Address address;
// Getter and Setter ...
}
Address.java
#Entity
#Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
#OneToOne
#MapsId
#JoinColumn(name = "id")
private User user;
// Getter and Setter ...
}
DeleteController.java
#Controller
public class DeleteController {
#Autowired
ServiceJpa serviceJpa;
#GetMapping(value = "/deleteAddressById")
public String deleteAddressById () {
serviceJpa.deleteAddressById(4L);
return "redirect:/home";
}
}
You got your mapping wrong thats all is the problem .
try the below and see
User.java
#Entity
#Table(name = "user", schema = "testCascade")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="foriegn key column in user table for address example.. address_id")
private Address address;
// Getter and Setter ...
}
Address.java
#Entity
#Table(name = "address", schema = "testCascade")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
//name of the address variable in your user class
#OneToOne(mappedBy="address",
cascade={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH})
private User user;
// Getter and Setter ...
}
In order to solve this problem, you need to read the hibernate Documentation Hibernate Example 162, Example 163, Example 164.
And also I recommend to look at this is Using #PrimaryKeyJoinColumn annotation in spring data jpa
This helped me in solving this problem.
And also you need to specify the parameter orphanRemoval = true
User.java
#Entity(name = "User")
#Table(name = "user", schema = "testother")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Address address;
public void addAddress(Address address) {
address.setUser( this );
this.address = address;
}
public void removeAddress() {
if ( address != null ) {
address.setUser( null );
this.address = null;
}
}
// Getter and Setter
}
Address.java
#Entity(name = "Address")
#Table(name = "address", schema = "testother")
public class Address implements Serializable {
#Id
private Long id;
#Column(name = "city")
private String city;
#OneToOne
#MapsId
#JoinColumn(name = "id")
private User user;
// Getter and Setter
}
DeleteController .java
#Controller
public class DeleteController {
#Autowired
ServiceJpa serviceJpa;
#GetMapping(value = "/deleteUser")
public String deleteUser () {
User user = serviceJpa.findUserById(2L).get();
user.removeAddress();
serviceJpa.saveUser(user);
return "/deleteUser";
}
}
Or make a custom SQL query.
#Repository
public interface DeleteAddress extends JpaRepository<Address, Long> {
#Modifying
#Query("delete from Address b where b.id=:id")
void deleteBooks(#Param("id") Long id);
}
public class Address {
#Id
private Long id;
#MapsId
#JoinColumn(name = "id")
private User user;
}
Rename #JoinColumn(name = "id") to #JoinColumn(name = "user_id")
You can't say that the column that will point to user will be the id of the Address

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

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;

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