Hibernate AssertionFailure空标识符PostgreSQL数据库

dsf9zpds  于 2022-11-14  发布在  PostgreSQL
关注(0)|答案(1)|浏览(146)

下面是另一个,因为我已经阅读了其余的,并试图实现修复,但无济于事。我的问题是我的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

如果你知道什么,请告诉我。我已经在这个问题上坚持了太久,只为了一个有趣的小副业。:(

qacovj5a

qacovj5a1#

我发现,我的一对一Map是错误的,我自动生成的ID在路上的某个地方出了问题。我认为这是一个错误,Hibernate没有意识到在新用户的情况下自动生成的ID实际上应该是空的。
尽管看起来令人困惑,但我的一对一Map最终如下所示:
在用户(父级)中:

@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;

请注意,我也手动进行了大量的Map。因此,如果您更多地依赖Hibernate的本机工作方式,那么这很可能不适用于您。(请参阅我的用户控制器以了解我的意思)。

相关问题