下面是另一个,因为我已经阅读了其余的,并试图实现修复,但无济于事。我的问题是我的User对象被正确保存(我可以看到它们弹出到数据库中),但是我的UserPreferences对象抛出了错误。这真的很奇怪,因为我现在正在显式地执行所有操作,并且可以肯定地知道,在对存储库进行“保存”调用时,Preferences对象中没有任何字段为空。最不重要的是“user”和“user_id”(PKEY)。
下面是UserPreferences的类:
package gbw.TheScheduler.models;
@Entity
@Table(name="user_preferences")
@JsonSerialize
public class UserPreferences implements Serializable {
static final long serialVersionUID = 828325321321L;
public static UserPreferences getDefault(User user){
return new UserPreferences(user,60);
}
public UserPreferences(){}
public UserPreferences(User user, int hours){
this.user = user;
this.userId = user.getId();
this.hours = hours;
this.timeslots = new HashSet<>();
}
@Id
@Column(name = "user_id")
private int userId;
private int hours;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "user_id")
private User user;
@OneToMany(mappedBy="preferences", fetch = FetchType.LAZY)
private Set<PreferencesTimeSlot> timeslots = new HashSet<>();
@JsonProperty
public int getHours(){
return hours;
}
@JsonProperty
public Set<PreferencesTimeSlot> getTimeslots(){
return timeslots;
}
public void setUser(User user){
this.user = user;
this.userId = user.getId();
}
public void setHours(int i){
this.hours = i;
}
public void setTimeslots(Set<PreferencesTimeSlot> list){
this.timeslots = list;
}
@JsonProperty
public int getId() {
return user.getId();
}
}
下面是我的“User”类:
package gbw.TheScheduler.models;
import static gbw.TheScheduler.util.ArrayUtil.*;
@Entity
@Table(name = "users")
@JsonSerialize
public class User implements Serializable {
static final long serialVersionUID = 321321321321L;
@Id
private int id;
@JsonProperty
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
private UserPreferences userPreferences;
@JsonProperty
@ManyToMany(fetch = FetchType.LAZY)
private Set<MonthlySchedule> schedules = new HashSet<>();
@JsonProperty("first_name")
@Column(name = "first_name")
private String firstName;
@JsonProperty("last_name")
@Column(name = "last_name")
private String lastName;
@JsonProperty("initials")
@Column(name = "initials")
private String initials;
@JsonProperty("email")
@Column(name = "email")
private String email;
@JsonProperty("password")
@Column(name = "password")
private String password;
@JsonProperty("admin")
@Column(name = "admin")
private boolean admin;
public User(@JsonProperty("initials") String initials, @JsonProperty("password") String password,
@JsonProperty("admin") boolean state, @JsonProperty("email") String email, @JsonProperty("first_name") String firstName,
@JsonProperty("last_name") String lastName){
this.initials = initials;
this.password = password;
this.admin = state;
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString(){
return initials + " " + password;
}
@JsonProperty
public Set<MonthlySchedule> getSchedules(){
return schedules;
}
@JsonProperty
public void setSchedules(Set<MonthlySchedule> schedules){
this.schedules = schedules;
}
@JsonProperty
public UserPreferences getPreferences(){
return userPreferences;
}
@JsonProperty
public void setPreferences(UserPreferences pref){
this.userPreferences = pref;
}
@JsonProperty
public int getId() {
return id;
}
@JsonProperty
public void setAdmin(boolean state){
admin = state;
}
@JsonProperty
public boolean isAdmin() {
return admin;
}
public void setId(int id) {
this.id = id;
}
@JsonProperty
public String getFirstName() {
return firstName;
}
@JsonProperty
public void setFirstName(String name) {
this.firstName = name;
}
@JsonProperty
public String getInitials() {
return initials;
}
@JsonProperty
public String getLastName(){
return lastName;
}
@JsonProperty
public void setInitials(String initials) {
this.initials = initials;
}
@JsonProperty
public String getEmail() {
return email;
}
@JsonProperty
public String getPassword() {
return password;
}
@JsonProperty
public void setEmail(String email) {
this.email = email;
}
public User(){}
@JsonProperty
public void setPassword(String password) {
this.password = password;
}
@JsonProperty
public void setLastName(String value) {
this.lastName = value;
}
}
下面是我的UserController,根据堆栈跟踪,问题出现在第68行:
@RequestMapping(path=path+"/add/{username}/{password}", method = RequestMethod.POST) // Map ONLY POST Requests
public @ResponseBody ResponseEntity<User> addNewUser (@RequestBody String requestText, @RequestHeader(required = false) String headerText, @PathVariable String username, @PathVariable String password) {
UserService.UserValidationResult validationBaseAccess = userService.validateUserAdminAccess(username,password);
if(validationBaseAccess.error() != null){
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
JSONWrapper parsed = new JSONWrapper(requestText);
User user = new User(
parsed.get("initials"),
parsed.get("password"),
BooleanUtil.parseOr(parsed.get("admin"), false),
parsed.get("email"),
parsed.getOr("first_name","Guest"),
parsed.getOr("last_name","User")
);
user.setId(userService.getValidId());
UserPreferences prefs = UserPreferences.getDefault(user);
User asSaved = userService.save(user);
prefRepo.save(prefs); <---------Issue occurs right here!
asSaved.setPreferences(prefs);
return new ResponseEntity<>(asSaved,HttpStatus.OK);
}
和堆栈跟踪:
org.hibernate.AssertionFailure: null identifier
at org.hibernate.engine.spi.EntityKey.<init>(EntityKey.java:51) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.internal.AbstractSharedSessionContract.generateEntityKey(AbstractSharedSessionContract.java:559) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.OneToOneType.isNull(OneToOneType.java:108) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.EntityType.resolve(EntityType.java:463) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.EntityType.resolve(EntityType.java:458) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.EntityType.replace(EntityType.java:359) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.AbstractType.replace(AbstractType.java:164) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:205) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:487) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:241) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:318) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:829) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
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.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-5.3.23.jar:5.3.23]
at jdk.proxy4/jdk.proxy4.$Proxy111.merge(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:669) ~[spring-data-jpa-2.7.3.jar:2.7.3]
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.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:530) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:286) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:640) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:139) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:81) ~[spring-data-commons-2.7.3.jar:2.7.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174) ~[spring-data-jpa-2.7.3.jar:2.7.3]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.23.jar:5.3.23]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.23.jar:5.3.23]
at jdk.proxy4/jdk.proxy4.$Proxy120.save(Unknown Source) ~[na:na]
at gbw.TheScheduler.controllers.UserController.addNewUser(UserController.java:68) ~[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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar:5.3.23]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.23.jar:5.3.23]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar:5.3.23]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.65.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar:5.3.23]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.65.jar:9.0.65]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
最后是我的应用程序。属性:
server.port=6969
security.ignored=/**
management.security.enabled=false
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.jpa.show-sql=false
spring.jpa.open-in-view=false
spring.datasource.username=postgres
spring.datasource.password=definetlyMyPassword
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL81Dialect
spring.main.allow-bean-definition-overriding=true
如果你知道什么,请告诉我。我已经在这个问题上坚持了太久,只为了一个有趣的小副业。:(
1条答案
按热度按时间qacovj5a1#
我发现,我的一对一Map是错误的,我自动生成的ID在路上的某个地方出了问题。我认为这是一个错误,Hibernate没有意识到在新用户的情况下自动生成的ID实际上应该是空的。
尽管看起来令人困惑,但我的一对一Map最终如下所示:
在用户(父级)中:
在用户首选项(子项)中:
请注意,我也手动进行了大量的Map。因此,如果您更多地依赖Hibernate的本机工作方式,那么这很可能不适用于您。(请参阅我的用户控制器以了解我的意思)。