我有一个带有简单Rest控制器,服务层和数据层的Spring Boot 2.1应用程序。我正在尝试禁用spring.jpa.open-in-view,因为我想管理集合的加载等。我的问题似乎是当我禁用了view-in时,我什么也回来不了控制器,包括带字符串的简单属性。
示例项目,以下代码的简化版:
https://github.com/csyperski/springbootopeninview
这是我的错误:
2019-02-05 09:06:19.591 -ERROR 11355 --- [nio-8081-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : 175 : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy [com.cwssoft.pscafepos.model.Item#268] - no Session] with root cause
-
org.hibernate.LazyInitializationException: could not initialize proxy [com.cwssoft.pscafepos.model.Item#268] - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:169) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at com.cwssoft.pscafepos.model.Item$HibernateProxy$h2GPuZuU.getBuilding(Unknown Source) ~[main/:na]
at com.cwssoft.pscafepos.controllers.ItemController.lambda$getSingle$3(ItemController.java:52) ~[main/:na]
at java.util.Optional.filter(Optional.java:178) ~[na:1.8.0_201]
at com.cwssoft.pscafepos.controllers.ItemController.getSingle(ItemController.java:52) ~[main/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.1.2.RELEASE.jar:5.1.2.RELEASE]
这是我的模型,没有getters / setter:
import com.cwssoft.pscafepos.model.converters.BooleanToStringConverter;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name="items", indexes = {
@Index(name="key_items_name", columnList="item_name"),
@Index(name="key_items_building", columnList="item_building"),
@Index(name="key_items_visible", columnList="item_visible"),
@Index(name="key_items_free", columnList="item_allowfree"),
@Index(name="key_items_reduced", columnList="item_allowreduced"),
@Index(name="key_items_typea", columnList="item_istypea"),
})
public class Item implements DomainObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id", updatable = false, nullable = false)
private Long id;
@Column(name="item_name", length = 100, nullable = false, unique = false)
private String name;
@Column(name="item_description", columnDefinition = "TEXT")
private String description;
@Column(name="item_price")
private double price;
@Column(name="item_building", length = 100, nullable = false, unique = false)
private String building;
@Column(name="item_category", columnDefinition = "TEXT")
private String category;
@Column(name="item_visible", length = 1, nullable = false, unique = false)
@Convert(converter= BooleanToStringConverter.class)
private boolean visible;
@Column(name="item_allowfree", length = 1, nullable = false, unique = false)
@Convert(converter=BooleanToStringConverter.class)
private boolean allowFree;
@Column(name="item_allowreduced",length = 1, nullable = false, unique = false)
@Convert(converter=BooleanToStringConverter.class)
private boolean allowReduced;
@Column(name="item_istypea",length = 1, nullable = false, unique = false)
@Convert(converter=BooleanToStringConverter.class)
private boolean typeA;
@Column(name="item_reducedprice")
private double reducedPrice;
@Column(name="item_addby", length = 100, nullable = false, unique = false)
private String addedBy;
@Column(name="item_adddate")
@Temporal(TemporalType.TIMESTAMP)
private Date createDate;
@Column(name="item_fr_bl")
private int freeReducedBreakfastLunch;
}
这是我的服务层:
package com.cwssoft.pscafepos.services;
import com.cwssoft.pscafepos.model.Item;
import com.cwssoft.pscafepos.repositories.ItemRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@Service
public class DefaultItemService extends BaseService<Item, ItemRepository> implements ItemService {
public DefaultItemService(ItemRepository itemRepository) {
super(itemRepository);
}
@Override
@Transactional
public Optional<Item> findByName(String name) {
if (name != null) {
return Optional.ofNullable(repository.findByName(name.trim()));
}
return Optional.empty();
}
@Override
@Transactional
public List<Item> findAll(String building) {
if (building != null) {
return repository.findByBuildingOrderByVisibleDescNameAsc(building.trim());
}
return Collections.emptyList();
}
}
和服务超类:
package com.cwssoft.pscafepos.services;
import com.cwssoft.pscafepos.model.DomainObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Slf4j
public abstract class BaseService<T extends DomainObject,U extends JpaRepository<T,Long>> implements CrudService<T,U> {
protected final U repository;
public BaseService(U repository) {
this.repository = repository;
}
public U getRepository() {
return repository;
}
@Transactional
public List<T> findAll() {
return repository.findAll();
}
@Transactional
public List<T> findAll(Sort sort) {
return repository.findAll(sort);
}
@Transactional
public List<T> findAllById(Iterable<Long> ids) {
return repository.findAllById(ids);
}
@Transactional
public Optional<T> save(T item) {
return Optional.ofNullable(repository.saveAndFlush(item));
}
@Transactional
public Optional<T> get(long id) {
return Optional.ofNullable(prepare(repository.getOne(id)));
}
@Transactional
public T prepare( T item ) {
return item;
}
@Transactional
public void delete(long id) {
get(id).ifPresent( repository::delete );
}
}
和控制器:
package com.cwssoft.pscafepos.controllers;
import com.cwssoft.pscafepos.model.AdminUser;
import com.cwssoft.pscafepos.model.Item;
import com.cwssoft.pscafepos.services.AdminUserService;
import com.cwssoft.pscafepos.services.ItemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
@RestController
@RequestMapping("/items")
@Slf4j
public class ItemController extends BaseController {
private final ItemService service;
public ItemController(ItemService itemService, AdminUserService adminUserService) {
super(adminUserService);
this.service = itemService;
}
@GetMapping("/all")
@Secured("CAFE_MANAGER")
public List<Item> all(Principal principal) {
return getLocation(principal)
.map( service::findAll )
.orElse( Collections.emptyList() );
}
@GetMapping("/single/{itemId}")
@Secured("CAFE_MANAGER")
public Item getSingle(Principal principal, @PathVariable("itemId") long id) {
final Optional<String> location = getLocation(principal);
location
.flatMap( l -> service.get(id) )
.ifPresent( item -> {
log.info("Item.toString {}", item);
});
return location
.flatMap( l -> service.get(id) )
.filter( item -> item.getBuilding() != null && item.getBuilding().equalsIgnoreCase(location.orElse(null)) )
.orElse( null );
}
}
那么我想念的是什么,为什么我不能撤回基本属性,Item类中没有集合,而且集合就这么简单。我看到我正在找回HibernateProxy包装的对象,当我尝试调用getBuilding时,它似乎失败了,即使构建只是一个简单的字符串。这一切都是在Jaskson尝试序列化对象以将其放在电线上之前进行的。谢谢!