исключение lazyload при загрузке объекта через данные пружины и f: viewAction, а затем доступ к одному из его свойств - PullRequest
0 голосов
/ 24 марта 2019

Я использую данные JSF, весеннюю загрузку и пружину для своего проекта.Я пытаюсь редактировать существующий объект.Для этого я передаю идентификатор объекта в качестве параметра в представление, а затем указываю f: viewAction, который просматривает базу данных и загружает объект.В результате я получаю Lazyloadexception "не удалось инициализировать прокси ... нет сеанса" позже, в другом методе, при вызове простого геттера для этого ЖЕ объекта (того же самого объекта, который я получил по id, а не объекта внутриколлекция или что-нибудь еще).

Я пытался:

  • помещать @Transactional как для класса бина JSF, так и для классов DAO
  • , помещая @Transactional для обоихМетод onload вызывается из f: viewAction и метод getter для объекта.
  • добавление spring.jpa.properties.hibernate.enable_lazy_load_no_trans = true в мои application.properties (да, я знаю, анти-паттерн, но работающее приложение, использующее анти-паттерн, лучше, чем приложение, которое не работаетВо всяком случае, независимо от того, что он ничего не сделал«решение», которое я мог найти после нескольких часов поиска этой ошибки.Я не уверен, что делать на этом этапе.У меня такое ощущение, что это как-то связано с порядком загрузки и вызовом DAO в методе f: viewAction.Может быть, он использует другой сеанс, который использует любой объект, который получает доступ к объекту с помощью методов?

    Извините, что включил в себя множество частей, я просто не знаю, в чем причина.Я подозреваю, что это где-то взаимодействие данных Spring, JPA и JSF.

    У меня была такая же ошибка, когда я пытался выполнить вызов базы данных для инициализации объектов в методе с аннотацией @PostConstruct.То, как я «решил» (читай: пропатчен), это было сделать вызов базы данных внутри геттера, который глуп (если (myobject == null) сделать вызов db. Иначе вернуть myobject)

    Ошибка:

    org.hibernate.LazyInitializationException: could not initialize proxy [mypackage.recipe.RecipeItem#8] - no Session
        at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:169)
        at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:309)
        at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
        at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
        at mypackage.recipe.RecipeItem$HibernateProxy$G4ytmgbe.getDisplayName(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    
    
    @EnableJpaRepositories(basePackages = "mypackage")
    @EnableTransactionManagement
    public class PersistenceConfig
    {
        // nothing here
    }
    

    @SpringBootApplication(scanBasePackages={"mypackage"})
    @EnableJpaRepositories(basePackages = "mypackage")
    @EnableTransactionManagement
    public class SpringBootTomcatApplication extends SpringBootServletInitializer {
        @Bean
        public JpaVendorAdapter jpaVendorAdapter() {
            HibernateJpaVendorAdapter bean = new HibernateJpaVendorAdapter();
            bean.setDatabase(Database.MYSQL);
            bean.setGenerateDdl(true);
            bean.setShowSql(true);
            return bean;
        }
    
        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
                JpaVendorAdapter jpaVendorAdapter) {
            LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
            bean.setDataSource(dataSource);
            bean.setJpaVendorAdapter(jpaVendorAdapter);
            bean.setPackagesToScan("mypackage");
            return bean;
        }
    
        @Bean
        public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
            return new JpaTransactionManager(emf);
        }
    }
    

    @Component
    @Transactional
    @Scope("session")
    public class EditRecipeItemControllerBean extends RecipeItemControllerBean
    {
        private Logger log = LoggerFactory.getLogger(this.getClass());
    
        @Transactional
        public void onload() {
            Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
            String recipeId = params.get("recipeId");
            log.info("from context recipe id: " + recipeId);
            //TODO error handling
            setRecipe(recipeDao.getOne(Long.valueOf(recipeId)));
        }
    
        public void submit() {
            super.save();
        }
    }       
    

    public class RecipeItemControllerBean implements Serializable
    {    
        private Logger log = LoggerFactory.getLogger(this.getClass());
        @Autowired
        AuthenticationFacade authenticationFacade;  
        @Autowired
        RecipeItemDao recipeDao;
    
        private RecipeItem recipe;
    
        /**
         * @return the recipe
         */
        public RecipeItem getRecipe()
        {
            return recipe;
        }
    
        /**
         * @param recipe the recipe to set
         */
        public void setRecipe(RecipeItem recipe)
        {
            this.recipe = recipe;
        }
    
        public void save() {
            log.debug("Saving recipe: " + recipe);
            recipeDao.save(recipe);
        }
    }
    

    @Entity
    @Table(name = "recipe_item")
    @NamedQueries(
    {
        // a bunch of named queries here
    })
    public class RecipeItem extends ClientSpecific
    {
        @Column(length = 256)
        private String description;
        @Lob
        @Column(name = "full_info", length = 65535)
        private String fullInfo;
        @Column(name = "thumbnail_uri", length = 1024)
        private String thumbnailUri;
        @Lob
        @Column(name = "preparation_instructions", length = 65535)
        private String preparationInstructions;
        @OneToMany(cascade = CascadeType.ALL, mappedBy = "recipeItem", fetch = FetchType.EAGER)
        private Collection<RecipeItemIngredients> recipeItemIngredients;
    
        public RecipeItem()
        {
        }
    
        //getters and setters 
    }
    

    @MappedSuperclass
    public abstract class ClientSpecific extends NamedBaseEntity
    {    
        @JoinColumn(name = "client_id", referencedColumnName = "id")
        @ManyToOne
        private Client client;
    
        public ClientSpecific()
        {
        }
    
        public ClientSpecific(Long id)
        {
            super(id);
        }
    
        public ClientSpecific(Long id, Client client)
        {
            super(id);
            this.client = client;
        }
    
        // getters and setters clipped for brevity
    }
    

    @MappedSuperclass
    public abstract class NamedBaseEntity extends BaseEntity
    {
        @Size(max = 64)
        @Column(name = "display_name")
        private String displayName;
    
        public NamedBaseEntity()
        {
        }
    
        public NamedBaseEntity(Long id)
        {
            super(id);
        }
        // gettes setters and tostring
    }
    

    @MappedSuperclass
    @JsonIgnoreProperties(value = {"updated", "created"})
    public abstract class BaseEntity implements Serializable
    {    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;
    
        @Column(name = "created")
        @Temporal(TemporalType.TIMESTAMP)
        private Date created;
    
        @Column(name = "updated")
        @Temporal(TemporalType.TIMESTAMP)
        private Date updated;
    
        @Column(name = "active")
        private Short active = (short) 1;
    
        public BaseEntity()
        {
        }
    
        public BaseEntity(Long id)
        {
            this.id = id;
        }
        // getters, settes, toString, hascode and equals
    }
    

    @Repository
    @Transactional
    @Component
    public interface RecipeItemDao extends JpaRepository<RecipeItem, Long>
    {
        // methods and implementation auto-generated by Spring Data
    }
    

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>mypackage.web</groupId>
        <artifactId>CoffeeShopWebApp</artifactId>
        <version>0</version>
        <packaging>war</packaging>
    
        <name>CoffeeShopWebApp</name>
    
        <properties>
            <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.1.2.RELEASE</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.hibernate.validator</groupId>
                        <artifactId>hibernate-validator</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>mypackage.base</groupId>
                <artifactId>myapplication-module-base</artifactId>
                <version>0</version>
            </dependency>
            <dependency>
                <groupId>org.joinfaces</groupId>
                <artifactId>joinfaces-dependencies</artifactId>
                <version>4.0.2</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.primefaces</groupId>
                <artifactId>primefaces</artifactId>
                <version>6.2</version>
            </dependency>
            <dependency>
                <groupId>org.primefaces.extensions</groupId>
                <artifactId>primefaces-extensions</artifactId>
                <version>6.2.10</version>
            </dependency>
            <dependency>
                <groupId>org.primefaces.extensions</groupId>
                <artifactId>resources-ckeditor</artifactId>
                <version>6.2.10</version>
            </dependency>
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>myapplication-recipe</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>5.1.4.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-web-api</artifactId>
                <version>7.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <compilerArguments>
                            <endorseddirs>${endorsed.dir}</endorseddirs>
                        </compilerArguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.6</version>
                    <executions>
                        <execution>
                            <phase>validate</phase>
                            <goals>
                                <goal>copy</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>${endorsed.dir}</outputDirectory>
                                <silent>true</silent>
                                <artifactItems>
                                    <artifactItem>
                                        <groupId>javax</groupId>
                                        <artifactId>javaee-endorsed-api</artifactId>
                                        <version>7.0</version>
                                        <type>jar</type>
                                    </artifactItem>
                                </artifactItems>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    spring.datasource.url=jdbc:mysql://myDatabaseStuff?zeroDateTimeBehavior=convertToNull
    spring.datasource.username=censored
    spring.datasource.password=censored
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.jmx.default-domain: censored
    spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
    spring.jpa.hibernate.ddl-auto=none
    server.error.whitelabel.enabled=false
    

1 Ответ

0 голосов
/ 25 марта 2019

Я понял это. Это не был мой транзакционный материал, как я и думал. Это был тот факт, что я использовал getOne () вместо findById ().

Это вопрос / ответ, который мне помог:

данные пружины jpa getOne throw LazyInitializationException и findBy not

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...