Ошибка IllegalArgumentException в Hibernate
При добавлении клиента в БД вылетает ошибка IllegalArgumentException. Класс ClientDetails
import com.example.BankService.model.Client;
import lombok.*;
import javax.persistence.*;
@Getter
@Setter
@Table(name = "clients_details")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class ClientDetails{
@Column(name = "id")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long ID;
@Embedded
private Client client;
}
Класс Client
import lombok.*;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import java.time.LocalDate;
@Getter
@Setter
@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class Client {
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "father_name")
private String fatherName;
@Column(name = "phone")
private String phone;
@Column(name = "email")
private String email;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "birth_day")
//@BirthDate(message = "Incorrect year")
private LocalDate birthDay;
@Column(name = "roles")
private String roles;
@Embedded
private BankAccount bankAccount;
}
Класс BankAccount
import lombok.*;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Getter
@Setter
@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class BankAccount {
@Column(name = "bank_account_id")
private Long id;
@Column(name = "initial_balance")
private float initialBalance;
@Column(name = "balance")
private float accountBalance;
}
Класс ClientDAOImpl
import com.example.BankService.entity.ClientDetails;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
@Repository
public class ClientDAOImpl implements ClientDAO{
@Autowired
Session session;
@Override
@Transactional
public void addClient(ClientDetails clientDetails) {
//Session session = getSession();
session.beginTransaction();
session.save(clientDetails);
session.close();
}
@Override
@Transactional
public ClientDetails findByUsername(String username) {
//Session session = getSession();
session.beginTransaction();
Query query = session.createQuery("FROM ClientDetails WHERE username = :username");
query.setParameter("username", username);
ClientDetails clientDetails = (ClientDetails) query.uniqueResult();
session.getTransaction().commit();
return clientDetails;
}
@Override
@Transactional
public void updateClient(ClientDetails clientDetails) {
//Session session = getSession();
session.beginTransaction();
session.update(clientDetails);
session.getTransaction().commit();
}
@Override
@Transactional
public void deleteClient(ClientDetails clientDetails) {
//Session session = getSession();
session.beginTransaction();
session.delete(clientDetails);
session.close();
}
@Override
@Transactional
public ClientDetails getClientDetailsById(long id) {
// Session session = getSession();
session.beginTransaction();
return session.get(ClientDetails.class, id);
}
public ClientDetails getClientDetailsByEmail(String email) {
var clients = getAllClientDetails();
for (ClientDetails client : clients){
if (client.getClient().getEmail().equals(email)){
return client;
}
}
return null;
}
@Override
@Transactional
public List<ClientDetails> getAllClientDetails() {
List<ClientDetails> clientDetailsList = session.createQuery("from ClientDetails").getResultList();
return clientDetailsList;
}
}
Класс RegisterController
@Controller
@RequestMapping("/register")
public class RegisterController {
private final RegisterProcessor registerProcessor;
private final BankAccountService bankAccountService;
private final LoginManagerService loginManagerService;
private final ClientDAOImpl clientDAOImpl;
private final PasswordEncoder passwordEncoder;
@Autowired
public RegisterController(RegisterProcessor registerProcessor,
BankAccountService bankAccountService,
LoginManagerService loginManagerService,
ClientDAOImpl clientDAOImpl, PasswordEncoder passwordEncoder) {
this.registerProcessor = registerProcessor;
this.bankAccountService = bankAccountService;
this.loginManagerService = loginManagerService;
this.clientDAOImpl = clientDAOImpl;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String register(Model model) {
model.addAttribute("client", new Client());
return "register.html";
}
@PostMapping
public String newRegister(@ModelAttribute("client") Client client,
Model model) {
registerProcessor.setEmail(client.getEmail());
boolean register = registerProcessor.register();
if (register) {
client.setPassword(passwordEncoder.encode(client.getPassword()));
client.setRoles("ROLE_USER");
BankAccount bankAccount = bankAccountService.createBankAccount();
client.setBankAccount(bankAccount);
ClientDetails clientDetails = new ClientDetails();
clientDetails.setClient(client);
clientDAOImpl.addClient(clientDetails);
loginManagerService.setID(client.getBankAccount().getId());
var clients = clientDAOImpl.getAllClientDetails();
model.addAttribute("clients", clients);
return "redirect:/login";
} else {
model.addAttribute("message", "A user with this email address already exists");
return "register.html";
}
}
}
Класс RegisterProcessor
@Component
@RequestScope
@Data
public class RegisterProcessor {
private ClientService clientService;
private LoginManagerService loginManagerService;
private String email;
@Autowired
public RegisterProcessor(ClientService clientService, LoginManagerService loginManagerService) {
this.clientService = clientService;
this.loginManagerService = loginManagerService;
}
public boolean register(){
var clients = clientService.findAll();
boolean notRegister = false;
for (Client client : clients){
if(email.equals(client.getEmail())){
return false;
}
}
loginManagerService.setEmail(email);
notRegister = true;
return notRegister;
}
}
Класс HibernateConfig
@Configuration
public class HibernateConfig {
@Bean
public Session getSession(){
SessionFactory factory = new org.hibernate.cfg.Configuration().configure("hibernate.cfg.xml")
.addAnnotatedClass(ClientDetails.class).buildSessionFactory();
return factory.openSession();
}
}
Файл hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:postgresql://localhost:5432/postgres</property>
<property name="connection.username">postgres</property>
<property name="connection.password">1</property>
<property name="current_session_context_class">jta</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL10Dialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="com.example.BankService.entity.ClientDetails"/>
</session-factory>
</hibernate-configuration>
Ну и стек ошибок (весь список не стал копировать, очень много места занимает)
2024-04-02T21:43:04.376+07:00 ERROR 12420 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private com.example.BankService.model.Client com.example.BankService.entity.ClientDetails.client] by reflection for persistent property [com.example.BankService.entity.ClientDetails#client] : ClientDetails(ID=null, client=Client(firstName=NIKOLAY, lastName=LABAZOV, fatherName=Konstantinovich, phone=89998586563, [email protected], username=qqqqq, password=$2a$10$nySaNfQzjp.MaAfgK6udTuTIJtMNNaX8rzL0iqAvaC8F5wDaJD0Fm, birthDay=1996-01-13, roles=ROLE_USER, bankAccount=BankAccount(id=108449914, initialBalance=13184.117, accountBalance=13184.117)))] with root cause
java.lang.IllegalArgumentException: Can not set com.example.BankService.model.Client field com.example.BankService.entity.ClientDetails.client to com.example.BankService.entity.ClientDetails
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) ~[na:na]
at java.base/java.lang.reflect.Field.get(Field.java:425) ~[na:na]
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:71) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.property.access.spi.GetterFieldImpl.getForInsert(GetterFieldImpl.java:90) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getPropertyValuesToInsert(AbstractEntityTuplizer.java:603) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.tuple.entity.PojoEntityTuplizer.getPropertyValuesToInsert(PojoEntityTuplizer.java:164) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValuesToInsert(AbstractEntityPersister.java:5377) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:194) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:179) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:672) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:665) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:660) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at com.example.BankService.dao.ClientDAOImpl.addClient(ClientDAOImpl.java:23) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.4.jar:6.1.4]
at com.example.BankService.dao.ClientDAOImpl$$SpringCGLIB$$0.addClient(<generated>) ~[classes/:na]
at com.example.BankService.controller.RegisterController.newRegister(RegisterController.java:56) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
В данном стеке ругается больше всего на метод save() класса ClientDAOImpl, хотя я не понимаю, что не так
Также стек ошибок, который указывает на то, что невозможно "достучаться" до поля ID класса ClientDetails
java.lang.IllegalArgumentException: Can not set java.lang.Long field com.example.BankService.entity.ClientDetails.ID to com.example.BankService.entity.ClientDetails
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) ~[na:na]
at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36) ~[na:na]
at java.base/java.lang.reflect.Field.get(Field.java:425) ~[na:na]
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:71) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:231) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5309) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:76) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:207) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:166) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:229) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at org.hibernate.query.Query.getResultList(Query.java:165) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
at com.example.BankService.dao.ClientDAOImpl.getAllClientDetails(ClientDAOImpl.java:83) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.4.jar:6.1.4]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:717) ~[spring-aop-6.1.4.jar:6.1.4]
at com.example.BankService.dao.ClientDAOImpl$$SpringCGLIB$$0.getAllClientDetails(<generated>) ~[classes/:na]
Здесь компилятор ругается на метод getAllClientDetails()
Также класс BankServiceApplication
@SpringBootApplication
public class BankServiceApplication {
public static void main(String[] args) {
System.setProperty("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
SpringApplication.run(BankServiceApplication.class, args);
}
}
Здесь костыль в виде System.setProperty..., который я применил по совету GPT, так как без него вылетало следующее
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig' defined in file [C:\Users\sesor\OneDrive\Рабочий стол\Programming\TestCase\BankService\target\classes\com\example\BankService\configurations\SecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'clientDAOImpl': Unsatisfied dependency expressed through field 'session': Error creating bean with name 'getSession' defined in class path resource [com/example/BankService/configurations/HibernateConfig.class]: Failed to instantiate [org.hibernate.Session]: Factory method 'getSession' threw exception with message: Unable to perform unmarshalling at line number 0 and column 0 in RESOURCE hibernate.cfg.xml. Message: null
Вот класс SecurityConfig
@Configuration
@ComponentScan(basePackages = "com.example")
public class SecurityConfig {
@Autowired
private ClientDAO clientDAO;
public SecurityConfig(ClientDAO clientDAO) {
this.clientDAO = clientDAO;
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService(ClientDAO clientDAO){
return new ClientService(clientDAO);
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((autorize) -> autorize
.requestMatchers("/edit", "/withdraw", "/transfer", "/home").authenticated()
.requestMatchers("/login", "/register").permitAll())
.formLogin(form -> form.loginPage("/login")
.defaultSuccessUrl("/home")).logout(logout -> logout.logoutSuccessUrl("/login"));
return http.build();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService(clientDAO));
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
}