没有与spring.jpa.open-in-view = false的会话

时间:2019-02-05 15:21:22

标签: java spring spring-boot jpa

我有一个带有简单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尝试序列化对象以将其放在电线上之前进行的。谢谢!

0 个答案:

没有答案