【问题标题】:Hibernate: @ManyToOne, @OneToMany gives nulls in resultHibernate:@ManyToOne,@OneToMany 在结果中给出空值
【发布时间】:2018-09-11 16:30:51
【问题描述】:

我有 java 应用程序(Spring + Hibernate)和 mySql DB。
Spring:5.0.2
休眠:5.2.12。

有两个实体 Student 和 Lesson。它们是相关的:一个学生对许多课程(课程表中的外键)。
代码:

@Entity
@Table(name = "students")
@XmlRootElement
public class Student implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   @Basic(optional = false)
   @Column(name = "student_id")
   private String studentId;

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "studentId")
   private Collection<Lesson> lessonCollection;

   // ...<other fields and some code>...
}    

@Entity
@Table(name = "lessons")
@XmlRootElement
public class Lesson implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   @Basic(optional = false)
   @Column(name = "lesson_id")
   private String lessonId;

   @JoinColumn(name = "student_id", referencedColumnName = "student_id")
   @ManyToOne(optional = false)
   private Student studentId;

   @Basic(optional = false)
   @Column(name = "number")
   private int number;

   // ...<other fields and some code>...
}

在 DB 中,学生和课程的所有字段均已填写。

我可以使用 Criteria API 成功选择所有学生。 但是当我选择课程(一个/全部)时,我有 Hibernate 异常:
org.hibernate.Property.AccessException: Null value was assigned to a property [class org.Lesson.number] of original type setter of org .Lesson.number.

如果我将字段“数字”更改为整数(可为空),那么我会得到这样的结果:
[null, null, null]
使用 HQL 发出请求会得到相同的结果。

有人可以给点建议吗?实体及其关系有什么问题?
提前谢谢!

更新:
获取结果代码:

public List<E> getAll() throws SQLException {
   CriteriaBuilder builder = curSession().getCriteriaBuilder();
   CriteriaQuery<? extends E> criteriaQuery = builder.createQuery(daoType);
   criteriaQuery.from(daoType);
   Query query = curSession().createQuery(criteriaQuery);
   try {
        System.out.println(query.getResultList());
   } catch (Throwable e) {
        throw new SQLException(e.getMessage()); // that's where it's fire
   }
}

结果必须类似于
[org.Lesson[lessonId=1], org.Lesson[lessonId=2], org.Lesson[lessonId=3]]

UPD2:
例外:

2018 年 2 月 2 日下午 4:38:18 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging org.apache.cxf.interceptor.Fault:空值是 分配给原始类型的属性 [class org.Lesson.number] org.Lesson.number 的设置器;嵌套异常是 org.hibernate.PropertyAccessException:空值被分配给 原始类型设置器的属性 [class org.Lesson.number] org.Lesson.number 在 org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162) 在 org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:267) 在 org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:128) 在 org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.invoke(AbstractJAXWSMethodInvoker.java:232) 在 org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:85) 在 org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:74) 在 org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126) 在 org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37) 在 org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131) 在 org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) 在 org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) 在 org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267) 在 org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) 在 org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) 在 org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) 在 org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:191) 在 org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301) 在 org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 在 org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 在 org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 引起: org.springframework.orm.hibernate5.HibernateSystemException:空 值已分配给属性 [class org.Lesson.number] org.Lesson.number 的原始类型设置器;嵌套异常是 org.hibernate.PropertyAccessException:空值被分配给 原始类型设置器的属性 [class org.Lesson.number] org.Lesson.number 在 org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:302) 在 org.springframework.orm.hibernate5.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:70) 在 org.springframework.orm.hibernate5.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:55) 在 org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) 在 org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) 在 com.sun.proxy.$Proxy44.getAll(未知来源) org.service.LessonServiceImpl.getAll(LessonServiceImpl.java:64) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) 在 com.sun.proxy.$Proxy45.getAll(未知来源) org.src.LessonWorkerImpl.getTasks(LessonWorkerImpl.java:155) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) 在 org.apache.cxf.jaxws.JAXWSMethodInvoker.performInvocation(JAXWSMethodInvoker.java:66) 在 org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ... 36 更多原因:org.hibernate.PropertyAccessException: Null 值已分配给属性 [class org.Lesson.number] org.Lesson.number 的原始类型设置器 org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:47) 在 org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:709) 在 org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:205) 在 org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4707) 在 org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:183) 在 org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:125) 在 org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1152) 在 org.hibernate.loader.Loader.processResultSet(Loader.java:1011) 在 org.hibernate.loader.Loader.doQuery(Loader.java:949) 在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) 在 org.hibernate.loader.Loader.doList(Loader.java:2692) 在 org.hibernate.loader.Loader.doList(Loader.java:2675) 在 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) 在 org.hibernate.loader.Loader.list(Loader.java:2502) 在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502) 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:384) 在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) 在 org.hibernate.internal.SessionImpl.list(SessionImpl.java:1490) 在 org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445) 在 org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414) 在 org.hibernate.query.Query.getResultList(Query.java:146) 在 org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:72) 在 org.dao.GenericDaoImpl.getAll(GenericDaoImpl.java:90) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ... 60 更多原因:java.lang.IllegalArgumentException:不能 设置 int 字段 org.kvant.suz.utils.data.db.domain.Task.executingStatus 为空值 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) 在 sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) 在 sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80) 在 java.lang.reflect.Field.set(Field.java:764) 在 org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:41) ... 90 更多

【问题讨论】:

  • 发布您的代码,包括显示结果的语句。准确地说出您期望的结果是什么,以及它实际上是什么。另外,请将studentId 重命名为student。这是学生证,不是学生证。
  • 已经更新的帖子
  • 包括显示结果的语句。准确说出您期望的结果是什么,以及它实际上是什么。不要抓住 Throwable。让异常传播,如果有异常则发布其堆栈跟踪。
  • 已经更新的帖子
  • 我以为您已经想出解决此异常的方法:原始 int 数字不可能包含 null,因此如果该列可以为 null,则类型应该是 Integer。如果该列中不应该有空值,则应在该列中添加一个非空约束,以使其不可能,并且应修复数据。

标签: java mysql spring hibernate jpa


【解决方案1】:

默认情况下 @OneToMany FetchTypeLazy 。这样它就不会被加载。如下所示更改您的映射。注意:FetchType 指定为Eager

@OneToMany(cascade = CascadeType.ALL, mappedBy = "studentId",fetch=FetchType.LAZY)
   private Collection<Lesson> lessonCollection;

getLessonCollection 将返回代理对象,该代理对象将具有实际对象的负载数据。

【讨论】:

  • 感谢。但是......您写道:“注意:FetchType 被指定为 Eager。”在你的 sn-p 中是“fetch=FetchType.LAZY”。真实在哪里?
  • 哦对不起.. FetchType.Eager 我的意思是
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多