我有两个问题阻碍了我的开发一段时间:
为什么会出现这种行为?这是应该预料到的吗?
@RequestMapping(value = "/get", method = RequestMethod.POST)
@ResponseBody
public Tenant data(@RequestParam("id") Long id) {
return tenantRepo.get(id);
}
(如果我不给@JsonIgnore,它会进入一个孩子内部父类的infinte循环并抛出错误)
2。 现在我将这个json传递给下面的控制器端点:
{
"type": "Student",
"numOfPeople": "1",
"tenantMembers": [
{
"firstName": "Chris",
"lastName": "C"
}
],
"tenantDetails": {
"firstName": "John",
"lastName": "J",
"email" "xyz@gmail.com"
}
}
@RequestMapping(value = "/set", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Tenant test(@RequestBody Tenant tenant) {
return tenantRepo.save(tenant);
}
(我得到了SQLERROR。我尝试删除外键约束,但仍然是同样的问题。)
我的父类:
@Entity
@Table(name = "tenant")
public class Tenant {
@GeneratedValue
@Id
private Long id;
private String type;
@Column(name = "num_of_people")
private String numOfPeople;
@OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<TenantMember> tenantMembers;
@OneToOne(mappedBy = "tenant", cascade = CascadeType.ALL)
private TenantDetails tenantDetails;
TenantMember儿童班:
@Entity
@Table(name = "tenant_member")
public class TenantMember {
@GeneratedValue
@Id
private Long id;
@ManyToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
private Tenant tenant;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
TenanatDetails子类:
@Entity
@Table(name="tenant_details")
public class TenantDetails {
@GeneratedValue
@Id
private Long id;
@OneToOne
@JoinColumn(name = "tenant_id")
@JsonIgnore
private Tenant tenant;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
private String email;
这是我的Hibernate配置:
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${hibernate.dialect}")
private String hibernateDialect;
@Value("${hibernate.show_sql}")
private String hibernateShowSql;
@Value("${hibernate.format_sql}")
private String hibernateFormatSql;
@Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
builder.scanPackages(new String[]{"com.example.demo.core.db.models"})
.addProperties(hibernateProperties());
return builder.buildSessionFactory();
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
//properties.put("hibernate.dialect", hibernateDialect);
properties.put("hibernate.show_sql", hibernateShowSql);
properties.put("hibernate.format_sql", hibernateFormatSql);
return properties;
}
@Bean
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
}
问题1的堆栈跟踪:
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: failed to lazily initialize a collection of role: com.example.demo.core.db.models.Tenant.tenantMembers, could not initialize proxy - no Session (through reference chain: com.example.demo.core.db.models.Tenant["tenantMembers"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.example.demo.core.db.models.Tenant.tenantMembers, could not initialize proxy - no Session (through reference chain: com.example.demo.core.db.models.Tenant["tenantMembers"])
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:272)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:153)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:165)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.demo.core.db.models.Tenant.tenantMembers, could not initialize proxy - no Session
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:579)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:203)
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:144)
org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261)
com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:102)
com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25)
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:600)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:148)
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1428)
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:930)
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:265)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:153)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:165)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
问题2的堆栈跟踪:(已编辑)
org.hibernate.exception.ConstraintViolationException: could not execute statement
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2827)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3398)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:597)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:232)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:213)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:256)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:254)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:234)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:853)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:835)
org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:260)
org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424)
org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:238)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:68)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:843)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:825)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:830)
com.example.demo.core.db.repos.base.impl.BaseRepoImpl.save(BaseRepoImpl.java:80)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy48.save(Unknown Source)
com.example.demo.web.controllers.TenantsController.test(TenantsController.java:30)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'tenant_id' cannot be null
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
com.mysql.jdbc.Util.getInstance(Util.java:387)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:932)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3878)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2478)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5094)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:42)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2827)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3398)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:597)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:232)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:213)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:256)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:318)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:275)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:113)
org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:254)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:234)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:853)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:835)
org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:260)
org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424)
org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:238)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:68)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:843)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:825)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:830)
com.example.demo.core.db.repos.base.impl.BaseRepoImpl.save(BaseRepoImpl.java:80)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
com.sun.proxy.$Proxy48.save(Unknown Source)
com.example.demo.web.controllers.TenantsController.test(TenantsController.java:30)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
答案 0 :(得分:1)
但它解释了为什么你会得到我认为的第一个例外。
您正在从控制器返回租户实例。 Tenant.tenantMembers是一个懒惰的集合。 当您从tenantRepo中读取Tenant时,Tenant.tenantMembers集合未加载,因为它很懒。 Spring在输入tenantRepo.get(id)之前打开一个事务,然后在它之后关闭它。当事务关闭时,hibernate会话也会关闭,并且无法加载空集合Tenant.tenantMembers。 杰克逊试图将租户转换为JSON并尝试阅读Tenant.tenantMembers。因为没有会话,所以抛出异常
com.example.demo.core.db.models.Tenant.tenantMembers, could not initialize proxy - no Session
当您在tenantMembers上添加@JsonIgnore时,Jackson不会触及该字段,您也不会获得例外。
要解决这个问题,你必须获取Tenant.tenantMembers EAGER,而不是LAZY。 这不会使您的应用程序变慢,因为您必须阅读整个集合,以将其作为JSON返回。 实现这一目标的最简单方法是改变
@OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL, fetch =
FetchType.EAGER)
private List<TenantMember> tenantMembers;
但如果你想在其他情况下获取LAZY,这可能不是你想要的。 您还可以使用方法get(Long id)创建TenatService,并注释ax @Transactional。 你可以在get(..)方法中进行
租户租户= tenantRepo.get(id); 。tenant.getTenantMembers()大小();
当您输入get(..)方法时,spring会打开一个新事务(因为@Transactional),从同一事务中的存储库中读取。 在集合上调用size()将加载它,因为事务仍处于打开状态,所以hibernate会这样做。 当get(..)离开时,spring关闭事务,但这没有问题,因为集合已经初始化。 多数民众赞成。
问题2 在提供的代码中,我找不到该异常的原因。 我建议在设置一个断点 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2551)
看看到底发生了什么。 在那里,或者在堆栈中你会看到hibernate想要编写的实体。通常情况下,这会为您提供有关出错的更多信息。 在堆栈跟踪中,您会看到ActionQueue,hibernate在事务结束时使用它来写入数据库。这种情况发生在交易关闭时,而不是在执行保存(..)时直接发生。 希望有所帮助。
关于评论:@Transactional,并调用size()但它不起作用 - 得到了相同的错误。 (在调用size()之前抛出的异常)...
嗨kukkuz,可能有理由获得异常,但是你得到相同的HttpMessageNotWritableException听起来不太可能。序列化将在很晚之后发生,因此在调用.size()之前接近该异常几乎是不可能的。
实际上堆栈跟踪显示,当请求离开控制器方法并且spring尝试将结果序列化为JSON时抛出异常。
您必须在注释为transactional的服务方法中调用.size()。在那里设置一个断点,你应该在调用服务方法之前在stacktrace中看到一个spring代理。如果不是,则表明您的事务管理不起作用。 您还可能必须使用服务接口,具体取决于配置/版本spring将仅创建接口的代理。 请发布该异常的堆栈跟踪以找到确切原因。
关于评论:对于问题2,已更新堆栈跟踪....
在堆栈跟踪中,您会看到hibernate尝试保存一对一的关系:
org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
所以问题一定是这种关系错误的定义:
@OneToMany(mappedBy = "tenant", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
私人名单租户成员;
我认为你的mappedBy在错误的一端。
如果关系是双向的,则非拥有方必须使用mappedBy
你拥有非自有的一面。