這是其中的一個,因為我已經閱讀了其余部分并嘗試實施修復,但無濟于事。我的問題是我的 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();
}
}
這是我的“用戶”類:
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]
最后是我的 application.properties:
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
如果你知道什么,請。對于一個有趣的小專案,我已經堅持了太久了。:(
uj5u.com熱心網友回復:
我發現,我的一對一映射是錯誤的,我的自動生成的 ID 在路上的某個地方出錯了。我認為這是一個錯誤,hibernate 沒有意識到在新用戶的情況下自動生成的 id 實際上應該為 null。
雖然看起來令人困惑,但我的一對一映射最終看起來像這樣:
在用戶(父)中:
@Id
@Column(name = "id")
private Long id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="id"<!CHILD ID-FIELD!>, referencedColumnName = "id"<!PARENT ID-FIELD!>)
private UserPreferences userPreferences;
在用戶首選項(子)中:
@Id
@Column(name = "id")
private Long id;
@OneToOne(mappedBy="userPreferences", fetch = FetchType.EAGER)
private User user;
請注意,我也手動進行了很多映射。因此,如果您更多地依賴 Hibernate 的本地處理方式,那么這很可能不適合您。(請參閱我的 UserController 以了解我的意思)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/528577.html
