Mapstruct does not create constructors with lombok - spring

In my project, I am using Lombok and mapstruct.
Here is my entity.
Wallet
package com.coin.cointracker.entity;
import lombok.*;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
#Entity
#Getter
#Setter
#NoArgsConstructor
#RequiredArgsConstructor
public class Wallet {
//Library
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#NonNull
private Long id;
#NonNull
private double InitialHolding;
#NonNull
private String currency;
#OneToMany(mappedBy = "wallet", cascade = CascadeType.REMOVE)
private Set<Transaction> transactions = new HashSet<>();
}
Here is DTO, WalletResponse
import lombok.*;
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public class WalletResponse {
private Long id;
private double InitialHolding;
private String currency;
}
WalletMapper
import com.coin.cointracker.dto.response.WalletResponse;
import com.coin.cointracker.entity.Wallet;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.Optional;
#Mapper(componentModel = "spring")
public interface WalletMapper {
WalletMapper map = Mappers.getMapper(WalletMapper.class);
//TODO: Is it problem to have Optional as type for parameter?
WalletResponse walletToWalletResponse(Optional<Wallet> wallet);
//Wallet walletRequestToWallet(WalletRequest walletRequest);
}
And lastly my pom.xml:
<properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.16</org.projectlombok.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
...
...
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.1.Final</version>
</dependency>
</dependencies>
...
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Beta2</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Repositories and services works fine. Repository successfully get data from db and services successfully calls mapper with data in database. But Mapper can not maps Wallet to WalletResponse.It results as this:
{
"id":null,
"InitialHolding":0.00,
"currency":null
}
Where did I make mistake?
EDIT : Here is generated WalletMapperImpl
package com.coin.cointracker.mapper;
import com.coin.cointracker.dto.response.WalletResponse;
import com.coin.cointracker.entity.Wallet;
import java.util.Optional;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;
#Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2021-01-25T19:41:00+0300",
comments = "version: 1.4.1.Final, compiler: javac, environment: Java 1.8.0_261 (Oracle Corporation)"
)
#Component
public class WalletMapperImpl implements WalletMapper {
#Override
public WalletResponse walletToWalletResponse(Optional<Wallet> wallet) {
if ( wallet == null ) {
return null;
}
WalletResponse walletResponse = new WalletResponse();
return walletResponse;
}
}

Related

Unauthorized and full authentication required to access user's resource

I am working on a resource service that uses Keycloak as the authorization server. The code below is taken from Spring Security in Action by Laurentiu Spilcă. Keycloak is provisioned with some users for testing purposes. So first a token for a user is obtained after login and the token is used to to make a request to retrieve the user's data from the resource server but I keep getting unauthorized and full authentication required. I am unable to figure out what the issue is as I am quite new to Spring.
KeycloakApplication.java
package com.chapter18.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories(basePackages = {"com.chapter18.repositories"} )
#EntityScan(basePackages = "com.chapter18.entities")
#ComponentScan(basePackages = {"com.chapter18.service", "com.chapter18.config", "com.chapter18.controller"})
public class KeycloakProjectApplication {
public static void main(String[] args) {
SpringApplication.run(KeycloakProjectApplication.class, args);
}
}
ResourceServerConfig.java
package com.chapter18.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.jwk.JwkTokenStore;
import org.springframework.security.web.FilterInvocation;
/**
* created on 21/04/2022
*/
#Configuration
#EnableResourceServer
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
#Value("${claim.aud}")
private String claimAud;
#Value("${jwkSetUri}")
private String urlJwk;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
System.out.println(claimAud + "\t" + urlJwk);
resources.tokenStore(tokenStore());
resources.resourceId(claimAud);
resources.expressionHandler(handler());
}
#Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.headers().frameOptions().disable();
// http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.mvcMatchers(HttpMethod.DELETE, "/**")
.hasAuthority("fitnessadmin")
.antMatchers("/h2-console/**").permitAll()
.anyRequest()
.authenticated();
}
#Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
#Bean
public SecurityExpressionHandler<FilterInvocation> handler() {
return new OAuth2WebSecurityExpressionHandler();
}
#Bean
public TokenStore tokenStore() {
return new JwkTokenStore(urlJwk);
}
}
WorkoutController.java
package com.chapter18.controller;
import com.chapter18.entities.Workout;
import com.chapter18.service.WorkoutService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* created on 21/04/2022
*/
#RestController
#RequestMapping("/workout")
public class WorkoutController {
#Autowired
private WorkoutService workoutService;
#PostMapping("/")
public void add(#RequestBody Workout workout){
workoutService.saveWorkout(workout);
}
#GetMapping("/")
public List<Workout> findAll(){
return workoutService.findWorkouts();
}
#DeleteMapping("/{id}")
public void delete(#PathVariable Integer id){
workoutService.deleteWorkout(id);
}
}
Workout.java
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;
/**
* created on 21/04/2022
*/
#Getter
#Setter
#Entity
public class Workout {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String user;
private LocalDateTime start;
private LocalDateTime end;
private int diffculty;
}
WorkoutRepository.java
package com.chapter18.repositories;
import com.chapter18.entities.Workout;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/**
* created on 21/04/2022
*/
public interface WorkoutRepository extends JpaRepository<Workout, Integer> {
#Query("SELECT w FROM Workout w WHERE w.user = ?#{authentication.name}")
List<Workout> findAllByUser();
}
WorkoutService
package com.chapter18.service;
import com.chapter18.entities.Workout;
import com.chapter18.repositories.WorkoutRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* created on 21/04/2022
*/
#Service
public class WorkoutService {
#Autowired
private WorkoutRepository workoutRepository;
#PreAuthorize("#workout.user == authentication.name and #oauth2.hasScope('fitnessapp')")
public void saveWorkout(Workout workout){
System.out.println(workout.getUser());
workoutRepository.save(workout);
}
public List<Workout> findWorkouts(){
return workoutRepository.findAll();
}
public void deleteWorkout(Integer id){
workoutRepository.deleteById(id);
}
}
application.yml
spring:
application:
name: FitnessApp
datasource:
url: jdbc:h2:mem:spring
username: sa
password: pass
driverClassName: org.h2.Driver
jpa:
spring:
jpa:
database-platform: org.hibernate.dialect.H2Dialect
defer-datasource-initialization: true
h2:
console:
enabled: true
sql:
init:
mode: ALWAYS
claim:
aud: fitnessapp
jwkSetUri: http://localhost:8080/realms/master/protocol/openid-connect/certs
server:
port: 9090
schema.sql
CREATE SCHEMA IF NOT EXISTS spring;
CREATE TABLE IF NOT EXISTS `spring`.`workout` (
`id` INT NOT NULL AUTO_INCREMENT,
`user` VARCHAR(45) NULL,
`start` DATETIME NULL,
`end` DATETIME NULL,
`difficulty` INT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `spring`.`workout` (`id`, `user`, `start`, `end`, `difficulty`) VALUES (1, 'bill', '2020-06-10 15:05:05', '2020-06-10 16:10:07', '3');
INSERT INTO `spring`.`workout` (`id`, `user`, `start`, `end`, `difficulty`) VALUES (2, 'rachel', '2020-06-10 15:05:10', '2020-06-10 16:10:20', '3');
INSERT INTO `spring`.`workout` (`id`, `user`, `start`, `end`, `difficulty`) VALUES (3, 'bill', '2020-06-12 12:00:10', '2020-06-12 13:01:10', '4');
INSERT INTO `spring`.`workout` (`id`, `user`, `start`, `end`, `difficulty`) VALUES (4, 'rachel', '2020-06-12 12:00:05', '2020-06-12 12:00:11', '4');
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.my</groupId>
<artifactId>KeycloakProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>KeycloakProject</name>
<description>KeycloakProject</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-data</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

#Valid annotation not working on Dto class - Spring Boot

I want validate my CustomerDTO using #Valid annotation.but also being validated at the same time using the #Valid annotation but it doesn't work, please help me.
This is my controller:
import lk.navishka.loginWithSecuruty.dto.CustomerDto;
import lk.navishka.loginWithSecuruty.entity.Customer;
import lk.navishka.loginWithSecuruty.service.CustomerService;
import lk.navishka.loginWithSecuruty.util.StandradResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RestController
#CrossOrigin
public class CustomerController {
#Autowired
CustomerService customerService;
#RequestMapping(value = {"/register"})
public ResponseEntity saveCustomer(#Valid #RequestBody CustomerDto customer){
customerService.saveCustomer(customer);
StandradResponse success = new StandradResponse(200, "success", null);
return new ResponseEntity(success, HttpStatus.OK);
}
}
this is My CustomerDTO class
import lombok.*;
import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#ToString
public class CustomerDto {
#NotNull
#Size(min = 9, message = "Nic have at least 9 characters ")
private String nic;
private String address;
#NotNull
#Size(min = 5, message = "FirstName have at least 5 characters ")
private String firstName;
#NotNull
#Size(min = 5, message = "LastName have at least 5 characters ")
private String lastName;
private ArrayList<UserDto> user = new ArrayList<>();
}
this is my ErrorDetails class
import java.util.Date;
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
this my ExceptionHandler class
import lk.navishka.loginWithSecuruty.util.ErrorDetails;
import lk.navishka.loginWithSecuruty.util.StandradResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Date;
#ControllerAdvice
public class ExceptionHandler {
//handling custom validation error
#ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> customValidationErrorHandling(MethodArgumentNotValidException exception){
ErrorDetails errorDetails = new ErrorDetails(new Date(),"Validator Error", exception.getBindingResult().getFieldError().getDefaultMessage());
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
}
i use meven this is Pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lk.navishka</groupId>
<artifactId>LoginWithSecuruty</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.4.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is the JSON value that i use with postman
{
"nic" : "656v",
"address" : "polpitiya",
"firstName" : "nn",
"lastName" : "",
"user": [{
"userName":"username1",
"email":"sample#gmail.com",
"password":"1234"
}]
}
Try the 6.2.0.final version of hibernate-validator, it will work.
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>

Spring Boot / MapStruct: Parameter 1 of constructor required a bean... Consider defining a bean of type

I don't know so much about Java, but I thought it should be enough to manage this little task...
I'm building a microservice, which provides Songs and list of songs via several Rest-Endpoints. But it doesn't just return a song when called, it also has to contact another service and enhance the song object with additional information. For this I implemented a Dto-Class and I use mapstruct to handle logic behind. I also did this in other projects with no problems. But now I'm struggling, because of this error, which I don't know how to solve - it says:
Parameter 1 of constructor in
mk.microservices.songsservice.services.SongServiceImpl required a bean
of type 'mk.microservices.songsservice.web.mapper.SongMapper' that
could not be found.
Action:
Consider defining a bean of type
'mk.microservices.songsservice.web.mapper.SongMapper' in your
configuration.
Here are excerpts from my code:
SongServiceImpl
import lombok.RequiredArgsConstructor;
import mk.microservices.songsservice.domain.Song;
import mk.microservices.songsservice.repositories.SongRepository;
import mk.microservices.songsservice.web.mapper.SongMapper;
import mk.microservices.songsservice.web.model.SongDto;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
#RequiredArgsConstructor
#Service
public class SongServiceImpl implements SongService {
private final SongRepository songRepository;
private final SongMapper songMapper;
#Override
public SongDto getSongById(Integer id) {
return songMapper.songToSongDto(songRepository.findById(id));
}
#Override
public List<Song> getAllSongs() {
return songRepository.findAll();
}
....
}
SongMapper
import org.mapstruct.DecoratedWith;
import java.util.Optional;
#MapStruct
#DecoratedWith(SongMapperDecorator.class)
public interface SongMapper {
SongDto songToSongDto(Optional<Song> song);
SongDto songToSongDtoWithSongInfo(Song song);
Song songDtoToSong(SongDto songDto);
}
SongMapperDecorator
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Optional;
public class SongMapperDecorator implements SongMapper {
private SongInfoService songInfoService;
private SongMapper mapper;
#Autowired
public void setMapper(SongMapper songMapper) { this.mapper = songMapper; }
#Override
public SongDto songToSongDto(Optional<Song> song) {
return mapper.songToSongDto(song);
}
#Override
public SongDto songToSongDtoWithSongInfo(Song song) {
SongDto songDto = mapper.songToSongDto(Optional.ofNullable(song));
SongInfo songInfo = songInfoService.getSongInfoBySongId(song.getId());
songDto.setDescription(songInfo.getDescription());
return songDto;
}
#Override
public Song songDtoToSong(SongDto songDto) {
return mapper.songDtoToSong(songDto);
}
}
Also did a clean, validate and compile without any errors. But when I did the verify, I got this:
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile
(default-compile) on project songs-service: Resolution of
annotationProcessorPath dependencies failed: Missing: [ERROR]
---------- [ERROR] 1) org.mapstruct:mapstruct-processor:jar:1.4.2
My POM looks like this:
The dependency for mapstruct:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
And the plugin for enabling mapstruct and lombok working together:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
Would be very glad, if someone could help me solving this. Already googled a lot and didn't find anything useful yet.
Br,
Mic
As it is clear from the error the SongServiceImpl requires a bean SongMapper but Mapstruct do not generate a spring bean by default. i,e it will not add #Component annotation in the generated class, so we need to explicitly mention to generate a class that can be used to create spring bean.
so instead of #MapStruct use #Mapper(componentModel = "spring") in the mapper interface.
Solved it finally, changed the mapstruct version in my POM to 1.4.2.Final (instead of just 1.4.2). Now it works...
Got the hint frome Mapstruct-Documentation here...
Solved this finally. I used this configuration (mapstruct + lombok)
Also installed m2e-apt plugin in eclipse.
pom.xml
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
------------------------------------------------------------
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
</configuration>

Why is PostPersist required to set the id of oneToOne child entity?

I am trying to implement bidirectional OneToOne Mapping and insert child entity(ProjectDetails.java) from parent entity(Project.java). However, entity manager is trying to insert null as id of child entity(ProjectDetails).
Error logs:
[EL Fine]: sql: 2019-08-19 01:16:50.969--ClientSession(1320691525)--Connection(926343068)--INSERT INTO project (name) VALUES (?)
bind => [Project]
[EL Fine]: sql: 2019-08-19 01:16:50.973--ClientSession(1320691525)--Connection(926343068)--SELECT ##IDENTITY
[EL Fine]: sql: 2019-08-19 01:16:50.983--ClientSession(1320691525)--Connection(926343068)--INSERT INTO project_details (project_id, details) VALUES (?, ?)
bind => [null, Details]
[EL Fine]: sql: 2019-08-19 01:16:50.986--ClientSession(1320691525)--SELECT 1
[EL Warning]: 2019-08-19 01:16:50.991--UnitOfWork(1746098804)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: Column 'project_id' cannot be null
Error Code: 1048
I have tried by removing insertable=false, and updatable=false from #OneToOne but it gives me error, that same column can't be referenced twice.
I have following entity classes.
Class : Project
package com.example.playground.domain.dbo;
import com.example.playground.jsonviews.BasicView;
import com.example.playground.jsonviews.ProjectView;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.Data;
import lombok.ToString;
import org.eclipse.persistence.annotations.JoinFetch;
import org.eclipse.persistence.annotations.JoinFetchType;
import javax.persistence.*;
#JsonView(BasicView.class)
#Data
#Entity
#Table(name = "project")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="project_id")
private Integer projectId;
#Column(name="name")
private String name;
#ToString.Exclude
#JsonView(ProjectView.class)
#OneToOne(mappedBy = "project", cascade = CascadeType.ALL, optional = false)
private ProjectDetails projectDetails;
}
Class : ProjectDetails
package com.example.playground.domain.dbo;
import com.example.playground.jsonviews.BasicView;
import com.example.playground.jsonviews.ProjectDetailsView;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.Data;
import lombok.ToString;
import javax.persistence.*;
#JsonView(BasicView.class)
#Data
#Entity
#Table(name = "project_details")
public class ProjectDetails {
#Id
#Column(name = "project_id")
private Integer projectId;
#ToString.Exclude
#JsonView(ProjectDetailsView.class)
#OneToOne
#JoinColumn(name = "project_id", nullable = false, insertable = false, updatable = false)
private Project project;
#Column(name = "details")
private String details;
}
class: ProjectController
package com.example.playground.web;
import com.example.playground.domain.dbo.Project;
import com.example.playground.jsonviews.ProjectView;
import com.example.playground.service.ProjectService;
import com.fasterxml.jackson.annotation.JsonView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping("/projects")
public class ProjectController {
#Autowired
private ProjectService projectService;
#GetMapping("/{projectId}")
#JsonView(ProjectView.class)
public ResponseEntity<Project> getProject(#PathVariable Integer projectId){
Project project = projectService.getProject(projectId);
return ResponseEntity.ok(project);
}
#PostMapping
#JsonView(ProjectView.class)
public ResponseEntity<Project> createProject(#RequestBody Project projectDTO){
Project project = projectService.createProject(projectDTO);
return ResponseEntity.ok(project);
}
}
class ProjectService
package com.example.playground.service;
import com.example.playground.domain.dbo.Project;
public interface ProjectService {
Project createProject(Project projectDTO);
Project getProject(Integer projectId);
}
class ProjectServiceImpl
package com.example.playground.impl.service;
import com.example.playground.domain.dbo.Project;
import com.example.playground.repository.ProjectRepository;
import com.example.playground.service.ProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
public class ProjectServiceImpl implements ProjectService {
#Autowired
private ProjectRepository projectRepository;
#Transactional
#Override
public Project createProject(Project projectDTO) {
projectDTO.getProjectDetails().setProject(projectDTO);
return projectRepository.saveAndFlush(projectDTO);
}
#Override
public Project getProject(Integer projectId) {
return projectRepository.findById(projectId).get();
}
}
JPAConfig
package com.example.playground.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
#Configuration
#EnableTransactionManagement(mode= AdviceMode.ASPECTJ)
public class JPAConfig{
#Bean("dataSource")
#ConfigurationProperties(prefix = "db1")
public DataSource getDataSource(){
return DataSourceBuilder.create().build();
}
#Bean("entityManagerFactory")
public LocalContainerEntityManagerFactoryBean getEntityManager(#Qualifier("dataSource") DataSource dataSource){
EclipseLinkJpaVendorAdapter adapter = new EclipseLinkJpaVendorAdapter();
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setPackagesToScan("com.example.playground.domain.dbo");
em.setDataSource(dataSource);
em.setJpaVendorAdapter(adapter);
em.setPersistenceUnitName("persistenceUnit");
em.setJpaPropertyMap(getVendorProperties());
return em;
}
#Bean(name = "transactionManager")
public JpaTransactionManager
transactionManager(#Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory)
{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
protected Map<String, Object> getVendorProperties()
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("eclipselink.ddl-generation", "none");
map.put("eclipselink.ddl-generation.output-mode", "database");
map.put("eclipselink.weaving", "static");
map.put("eclipselink.logging.level.sql", "FINE");
map.put("eclipselink.logging.parameters", "true");
map.put(
"eclipselink.target-database",
"org.eclipse.persistence.platform.database.SQLServerPlatform");
return map;
}
}
and pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>playground</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Java-Spring-Boot-Playground</name>
<description>Java playground.</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.7.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jdbc -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>9.0.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Edit : Got it working, but still looking for explaination
If I add below code to my Project class , It works as expected.
#PostPersist
public void fillIds(){
projectDetails.setProjectId(this.projectId);
}
Buy why is postPersist required? Isn't JPA suppose to autofill these values given the relation is marked as oneToOne? Is there any better way?
JPA is following what you instructed it to do: You have two mappings to the "project_id", and the one with a value, the OneToOne is read-only. This means JPA must pull the value from the basic ID mapping 'projectId' which you have left as null, causing it to insert null into the field.
This is a common issue and there are a number of solutions within JPA. First would have been to mark the #ID mapping as read-only (insertable/updatable=false) and let the relationship mapping control the value.
JPA 2.0 brought in other solutions though.
For this same setup, you can mark the relationship with the #MapsId annotation. This tells JPA that the relationship foreign key value is to be used in the specified ID mapping, and will set it for you exactly as you seem to expect without the postPersist method.
Another alternative in JPA 2.0 is that you can just mark the OneToOne as the ID mapping, and remove the projectId property from the class. A more complex example is shown here

"javax.persistence.SynchronizationType"'s signer information does not match signer information of other classes in the same package

I am trying to connect to Oracle data base using JPA through a Spring Boot Application. I initially got the error saying
java.lang.NoSuchMethodError: javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType
I did a search on how to recitify the same and found that o resolve the same I should use version from 2.1.0 for the javax.persistence dependency.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.0</version>
</dependency>
Upon changing the same, the error is resolved, but I am getting another error now:
java.lang.SecurityException: class "javax.persistence.SynchronizationType"'s signer information does not match signer information of other classes in the same package
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.in28minutes</groupId>
<artifactId>in28Minutes-first-webapp</artifactId>
<version>2.1.3.RELEASE</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2.2</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>12.1.0.2</version>
</dependency>
<!-- Java 8 = JAX-B Version 2.2.8 added to correct missing entity manager error-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.3.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<verbose>true</verbose>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<contextReloadable>true</contextReloadable>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
My application class:
package com.myfirst.classes.from.db;
import java.util.Date;
//import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
//import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Component;
//import com.example.database.databasejdbcdemo.SpringDataDemoApplication;
/*#EnableAutoConfiguration(exclude = {
JndiConnectionFactoryAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
SecurityAutoConfiguration.class,DataSourceAutoConfiguration.class })*/
//#EnableJpaRepositories(basePackages="com.myfirst.classes.from.db")
#ComponentScan("com.myfirst.classes.from.db")
#SpringBootApplication
public class SpringDataDemoApplication implements CommandLineRunner{
//private org.slf4j.Logger logger= LoggerFactory.getLogger(this.getClass());
#Autowired
PersonSpringDataRepository repository ;
public static void main(String[] args) {
SpringApplication.run(SpringDataDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("hello");
//logger.info("Person with ID 10002 ->{}",repository.findById(10002));
//logger.info("Updating person with ID 10002 ->{}",repository.save(new Person(10002,"Kunjol","Home",new Date())));
//logger.info("Person with ID 10002 ->{}",repository.findById(10002));
//logger.info("Inserting a new person now ->{}",repository.save(new Person(10007,"Karthik","Home",new Date())));
//logger.info("Person with ID 10007 ->{}",repository.findByName("Karthik"));
//repository.deleteById(10001);
//logger.info("Person with ID 10001 ->{}",repository.findById(10001));
}
}
PersonSpringDataRepository.java
package com.myfirst.classes.from.db;
import javax.persistence.EntityManagerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Component
#Transactional
public interface PersonSpringDataRepository extends JpaRepository<Person,Integer> {
}
And the Person.java
package com.myfirst.classes.from.db;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
#Entity
#Table(name="person")
#Configuration
#ConfigurationProperties("oracle")
public class Person {
// private EntityManagerFactory entityManagerFactory;
#Id
#GeneratedValue
// #Bean
private int id;
private String name;
private String location;
private Date birth_date;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Date getBirth_date() {
return birth_date;
}
public void setBirth_date(Date birth_date) {
this.birth_date = birth_date;
}
public Person(int id, String name, String location, Date birth_date) {
super();
this.id = id;
this.name = name;
this.location = location;
this.birth_date = birth_date;
}
public Person( String name, String location, Date birth_date) {
super();
this.name = name;
this.location = location;
this.birth_date = birth_date;
}
public Person()
{
//By default, Spring will try to instantiate beans by calling a default (no-arg) constructor.
}
#Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", location=" + location + ", birth_date=" + birth_date + "]";
}
}
What could be the possible reason for the issue? Any help would be highly appreciated.
I have the same error now. The root cause is that eclipselink jar contains class javax.persistence.SynchronizationType, but it also brings another dependency (jakarta.persistence) which also contains the same class - and the one that actually gets used is from other jar (and signed by other cert) than the rest of the package.
With that said, I could not find a straight solution for this. IMO the problem is in eclipselink bringing the same class twice and until that is fixed, we can only look for workarounds.
EDIT: Here is another thread which has a solution (exclude JPA API from eclipselink and bring in another one which isn't signed)
Ended up excluding jakarta.persistence in favor of hibernate-jpa-2.1-api jar and that worked!
Until, EL team becomes active and respond to https://bugs.eclipse.org/bugs/show_bug.cgi?id=549240

Resources