С операцией CRUD Micronaut REST API в таблице с внешними ключами не работает
Мы создали приложение micronaut с JPA и менеджером сущностей. У нас есть таблица с именем Employee и State, поэтому мы создали классы сущностей для обоих и сослались на state_id в таблице сотрудников.
Со всей реализацией мы можем получить данные о сотруднике с идентификатором состояния и именем, но когда мы создаем нового сотрудника, он выдает ошибки.
Модель сотрудника:
package io.usermgmt.models;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id")
private Integer employeeId;
@Column(name = "employee_name")
private String employeeName;
@Column(name = "address")
private String address;
@Column(name = "city")
private String city;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "state_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private State state;
@Column(name = "zip_code")
private String zipCode;
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getAddress(){return address;}
public void setAddress(String address){this.address=address;}
public String getCity(){return city;}
public void setCity(String city){this.city=city;}
public Integer getStateId(){return state.getStateId();}
public String getStateName(){return state.getStateName();}
public String getZipCode(){return zipCode;}
public void setZipCode(String zipCode){this.zipCode=zipCode;}
}
Государственная модель:
package io.usermgmt.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Proxy;
import javax.persistence.Column;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "state")
@Proxy(lazy = false)
public class State {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "state_id")
private Integer stateId;
@Column(name = "state_name")
private String stateName;
@OneToMany(mappedBy = "state", fetch = FetchType.LAZY)
@JsonIgnore
private Set<Employee> employees = new HashSet<>();
public Integer getStateId() { return this.stateId; }
public void setStateId(Integer stateId){
this.stateId = stateId;
}
public String getStateName(){ return this.stateName; }
public void setStateName(String stateName){
this.stateName = stateName;
}
}
СотрудникРепозиторийИмпл
package io.usermgmt.repositories.impl;
import io.usermgmt.models.Client;
import io.usermgmt.repositories.IEmployeeRepository;
import io.micronaut.configuration.hibernate.jpa.scope.CurrentSession;
import io.micronaut.spring.tx.annotation.Transactional;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;
@Singleton
public class EmployeeRepositoryImpl implements IEmployeeRepository {
@PersistenceContext
private EntityManager entityManager;
public EmployeeRepositoryImpl(@CurrentSession EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
@Transactional
public Employee createEmployee(@NotNull Employee employee) {
entityManager.persist(employee);
return employee;
}
@Override
@Transactional
public Employee updateEmployee(@NotNull Employee employee) {
return entityManager.merge(employee);
}
@Override
@Transactional(readOnly = true)
public List<Employee> getAllEmployees() {
String qlString = "SELECT c FROM Employee c";
TypedQuery<Employee> query = entityManager.createQuery(qlString, Employee.class);
return query.getResultList();
}
@Override
@Transactional(readOnly = true)
public Optional<Employee> getEmployeeById(@NotNull Integer id) {
return Optional.ofNullable(entityManager.find(Employee.class, id));
}
}
getAllEmployees() работает нормально, также получая данные о состоянии. Но при его создании ниже ошибки.
ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error encoding object [io.usermgmt.models.Employee@1d91f388] to JSON: (was j
ava.lang.NullPointerException) (through reference chain: io.usermgmt.models.Employee["stateId"])
io.micronaut.http.codec.CodecException: Error encoding object [io.usermgmt.models.Employee@1d91f388] to JSON: (was java.lang.NullPointerException) (through reference chain: io.app
ter.clientmgmt.models.Employee["stateId"])
at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:176)
at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:182)
at io.micronaut.http.server.netty.RoutingInBoundHandler.encodeBodyAsByteBuf(RoutingInBoundHandler.java:1359)
at io.micronaut.http.server.netty.RoutingInBoundHandler.encodeBodyWithCodec(RoutingInBoundHandler.java:1305)
at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$subscribeToResponsePublisher$16(RoutingInBoundHandler.java:1240)
at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:63)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapSubscriber.drain(FlowableSwitchMap.java:307)
at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapInnerSubscriber.onSubscribe(FlowableSwitchMap.java:366)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onSubscribe(InstrumentedSubscriber.java:75)
at io.reactivex.internal.operators.flowable.FlowableJust.subscribeActual(FlowableJust.java:34)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.micronaut.reactive.rxjava2.RxInstrumentedCallableFlowable.subscribeActual(RxInstrumentedCallableFlowable.java:65)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapSubscriber.onNext(FlowableSwitchMap.java:129)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onNext(FlowableSubscribeOn.java:97)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.micronaut.http.context.ServerRequestTracingPublisher$1.lambda$onNext$1(ServerRequestTracingPublisher.java:60)
at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
at io.micronaut.http.context.ServerRequestTracingPublisher$1.onNext(ServerRequestTracingPublisher.java:60)
at io.micronaut.http.context.ServerRequestTracingPublisher$1.onNext(ServerRequestTracingPublisher.java:52)
at io.reactivex.internal.util.HalfSerializer.onNext(HalfSerializer.java:45)
at io.reactivex.internal.subscribers.StrictSubscriber.onNext(StrictSubscriber.java:97)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FlowableSwitchIfEmpty.java:59)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:68)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
at io.reactivex.internal.operators.flowable.FlowableCreate$NoOverflowBaseAsyncEmitter.onNext(FlowableCreate.java:403)
at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildResultEmitter$19(RoutingInBoundHandler.java:1430)
at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:71)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.internal.operators.flowable.FlowableMap.subscribeActual(FlowableMap.java:37)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14868)
at io.micronaut.http.context.ServerRequestTracingPublisher.lambda$subscribe$0(ServerRequestTracingPublisher.java:52)
at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
at io.micronaut.http.context.ServerRequestTracingPublisher.subscribe(ServerRequestTracingPublisher.java:52)
at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
at io.reactivex.Flowable.subscribe(Flowable.java:14918)
at io.reactivex.Flowable.subscribe(Flowable.java:14865)
at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:253)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: io.usermgmt.models.Employee["stateId"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:727)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3905)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsBytes(ObjectMapper.java:3243)
at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:173)
... 69 common frames omitted
Caused by: java.lang.NullPointerException: null
at io.usermgmt.models.Employee.getStateId(Employee.java:83)
at io.usermgmt.models.$Employee$Introspection$$5.readInternal(Unknown Source)
at io.micronaut.core.beans.AbstractBeanProperty.get(AbstractBeanProperty.java:116)
at io.micronaut.jackson.modules.BeanIntrospectionModule$BeanIntrospectionPropertyWriter.serializeAsField(BeanIntrospectionModule.java:539)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
... 75 common frames omitted
данные, которые мы передаем через poastman:
{
"employeeName": "ATT",
"address": "address",
"city": "HYD",
"isActive": true,
"stateId": 1,
"countryName": "India",
"countryId": 2,
"stateName": "telangana"
}
Может ли кто-нибудь помочь в этом, пожалуйста.