@OneToMany @JoinTable failed to lazily initialize a collection Fehler

Diskutiere @OneToMany @JoinTable failed to lazily initialize a collection Fehler im Datenbankprogrammierung Forum; Ich erstelle mir gerad ein Projekt. Folgend ein Auszug daraus. Ich habe eine Entity "Project" und "File". Ein Project kann beliebig viele Files...

  1. Schuriko
    Schuriko Neues Mitglied
    Ich erstelle mir gerad ein Projekt. Folgend ein Auszug daraus. Ich habe eine Entity "Project" und "File". Ein Project kann beliebig viele Files haben. Also eine OneToMany. Da ich File noch an anderer Stelle verwende verbinde ich die beiden über eine Join-Table.

    Code (Java):
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;

    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.Lob;
    import javax.persistence.OneToMany;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;

    import org.hibernate.annotations.CreationTimestamp;
    import org.hibernate.annotations.UpdateTimestamp;

    @Entity
    @Table(name="projects")
    public class Project {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
       
        @CreationTimestamp
        private Date    created_at;
       
        @OneToOne(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER)
        @JoinColumn(name="created_by")      
        private User    created_by;
       
        @UpdateTimestamp
        private Date    updated_at;
       
        @OneToOne(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER)  
        @JoinColumn(name="updated_by")      
        private User    updated_by;  
       
        @NotNull
        private Boolean    published = false;
       
        @Size(min=3, max=255)
        @NotBlank      
        private String    name;

        @Size(min=3, max=10)
        private String    key;
       
        @Max(255)
        private String    symbol;
       
        private Integer    color = 0;
       
        @Lob
        private String    description;

        @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
        @JoinColumn(name = "project_files")  
        private List<File> files = new ArrayList<>();
       
        public Project() {
            super();
        }
       
        public Project(@Size(min = 3, max = 255) @NotBlank String name) {
            super();
            this.name = name;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public Date getCreatedAt() {
            return created_at;
        }

        public void setCreatedAt(Date created_at) {
            this.created_at = created_at;
        }

        public User getCreatedBy() {
            return created_by;
        }

        public void setCreatedBy(User created_by) {
            this.created_by = created_by;
        }

        public Date getUpdatedAt() {
            return updated_at;
        }

        public void setUpdatedAt(Date updated_at) {
            this.updated_at = updated_at;
        }

        public User getUpdatedBy() {
            return updated_by;
        }

        public void setUpdatedBy(User updated_by) {
            this.updated_by = updated_by;
        }

        public Boolean getPublished() {
            return published;
        }

        public void setPublished(Boolean published) {
            this.published = published;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getSymbol() {
            return symbol;
        }

        public void setSymbol(String symbol) {
            this.symbol = symbol;
        }

        public Integer getColor() {
            return color;
        }

        public void setColor(Integer color) {
            this.color = color;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public List<File> getFiles() {
            return files;
        }

        public void setFiles(List<File> files) {
            this.files = files;
        }

        @Override
        public String toString() {
            return "Project [id=" + id + ", created_at=" + created_at + ", created_by=" + created_by + ", updated_at="
                    + updated_at + ", updated_by=" + updated_by + ", published=" + published + ", name=" + name + ", key="
                    + key + ", symbol=" + symbol + ", color=" + color + ", description=" + description + ", files=" + files
                    + "]";
        }
           
    }
     
    Code (Java):
    import java.util.Date;

    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.Lob;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    import javax.validation.constraints.NotBlank;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;

    import org.hibernate.annotations.CreationTimestamp;
    import org.hibernate.annotations.UpdateTimestamp;

    @Entity
    @Table(name="files")
    public class File {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
       
        @CreationTimestamp
        private Date    created_at;
       
        @OneToOne(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER)
        @JoinColumn(name="created_by")      
        private User    created_by;
       
        @UpdateTimestamp
        private Date    updated_at;
       
        @OneToOne(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER)  
        @JoinColumn(name="updated_by")      
        private User    updated_by;      
       
        @NotNull
        private Boolean    published = false;
       
        @Size(min=3, max=255)
        @NotBlank      
        private String    name;
       
        @Lob
        private String    description;
       
        @Size(min=3, max=255)
        @NotBlank      
        private String    filename;

        private String    type;
       
        public File() {
            super();
        }
       
        public File(@Size(min = 3, max = 255) @NotBlank String name, @Size(min = 3, max = 255) @NotBlank String filename) {
            super();
            this.name = name;
            this.filename = filename;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public Date getCreatedAt() {
            return created_at;
        }

        public void setCreatedAt(Date created_at) {
            this.created_at = created_at;
        }

        public User getCreatedBy() {
            return created_by;
        }

        public void setCreatedBy(User created_by) {
            this.created_by = created_by;
        }

        public Date getUpdatedAt() {
            return updated_at;
        }

        public void setUpdatedAt(Date updated_at) {
            this.updated_at = updated_at;
        }

        public User getUpdatedBy() {
            return updated_by;
        }

        public void setUpdatedBy(User updated_by) {
            this.updated_by = updated_by;
        }

        public Boolean getPublished() {
            return published;
        }

        public void setPublished(Boolean published) {
            this.published = published;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getFilename() {
            return filename;
        }

        public void setFilename(String filename) {
            this.filename = filename;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        @Override
        public String toString() {
            return "File [id=" + id + ", created_at=" + created_at + ", created_by=" + created_by + ", updated_at="
                    + updated_at + ", updated_by=" + updated_by + ", published=" + published + ", name=" + name
                    + ", description=" + description + ", filename=" + filename + ", type=" + type + "]";
        }  
       
       
    }
    Code (Java):
    import java.util.List;

    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.data.repository.CrudRepository;

    import com.abado.pts.entities.File;

    public interface FileRepository extends CrudRepository<File, Long> {
        @Modifying
        @Query("delete from File f where f.id in ?1")
        void deleteWithIds(List<Long> ids);
       
        @Modifying
        @Query("update File set published = ?2 where id = ?1")
        void setPublished(Long id, Boolean publish);

        @Modifying
        @Query("update File set published = ?2 where id in ?1")
        void publishWidthIds(List<Long> ids, Boolean published);

    }
    Code (Text):
    import java.util.List;

    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.data.repository.CrudRepository;

    import com.abado.pts.entities.Project;

    public interface ProjectRepository extends CrudRepository<Project, Long> {
       
        @Modifying
        @Query("delete from Project p where p.id in ?1")
        void deleteWithIds(List<Long> ids);
       
        @Modifying
        @Query("update Project set published = ?2 where id = ?1")
        void setPublished(Long id, Boolean publish);
       
        @Modifying
        @Query("update Project set published = ?2 where id in ?1")
        void publishWidthIds(List<Long> ids, Boolean published);
    }
     
    Code (Java):
    iimport java.util.Optional;

    import javax.transaction.Transactional;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import com.abado.pts.entities.Language;
    import com.abado.pts.entities.Project;
    import com.abado.pts.repositories.LanguageRepository;
    import com.abado.pts.repositories.ProjectRepository;

    @Service
    @Transactional
    public class ProjectService {
       
        @Autowired
        ProjectRepository projectRepository;
       
        public Project save(Project project) {
            return projectRepository.save(project);
        }

        public Optional<Project> findById(Long id) {
            return projectRepository.findById(id);
        }
    }
    Code (Java):
    import static org.junit.Assert.*;

    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Optional;

    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;

    import com.abado.pts.entities.File;
    import com.abado.pts.entities.Project;
    import com.abado.pts.repositories.FileRepository;
    import com.abado.pts.repositories.ProjectRepository;

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ProjectServiceTest {
       
        @Autowired
        ProjectService projectService;
       
        @Autowired
        ProjectRepository projectRepository;

        @Autowired
        FileRepository fileRepository;
       
        @Before
        public void setUp() throws Exception {
        }

        /**
         * test save without files
         */

        @Test
        public void testSaveWithoutFiles() {
            String  projectnameValue = "Project 1";
            Project project = new Project(projectnameValue);
           
            projectService.save(project);
           
            Optional<Project> foundProject = projectService.findById(project.getId());
           
            assertTrue(foundProject.isPresent());
            assertNotNull(foundProject.get().getCreatedAt());
            assertNotNull(foundProject.get().getUpdatedAt());
           
            // clear
            projectRepository.deleteAll();
            fileRepository.deleteAll();
        }
       
        /**
         * test save with files
         */

        @Test
        public void testSaveWithUnstoredFiles() {
            String  projectnameValue = "Project 1";
            List<File> files = new ArrayList<>();
            Project project = new Project(projectnameValue);
           
            files.add(new File("name1", "filename1"));
            files.add(new File("name2", "filename2"));
            files.add(new File("name3", "filename3"));

            assertEquals(3, files.size());
           
            project.setFiles(files);
            assertEquals(3, project.getFiles().size());
           
            assertNotNull(projectService.save(project));
           
            Optional<Project> foundProject = projectService.findById(project.getId());
           
            assertTrue(foundProject.isPresent());
            assertEquals("File Count: " + foundProject.get().getFiles().size(), 3, foundProject.get().getFiles().size());

            // clear
            projectRepository.deleteAll();
            fileRepository.deleteAll();
        }
       
    }
     
    Beim Test erhalte ich folgende Fehlermeldung
    Ich verstehe nur nicht so ganz was ich falsch mache.
     
  2. Java online lernen
  3. httpdigest
    httpdigest Bekanntes Mitglied
    Das Problem ist, dass du auf eine noch nicht initialisierte (weil lazy - @OneToMany werden per Default lazy nachgeladen) Collection Project.getFiles() außerhalb einer Transaktion innerhalb der Testmethode ProjectServiceTest.testSaveWithUnstoredFiles() zugreifst. Deine Transaktion erstreckt sich nur über den Service, aber eben nicht über deinen Unit-Test. Deshalb kann Hibernate die Datenbank nicht mehr fragen, um die Files eines Projektes nachzuladen.
    Entweder, du lässt deine Transaktion über deinen Test erstrecken, oder du nutzt @OneToMany(fetch=EAGER).
     
  4. Schuriko
    Schuriko Neues Mitglied
    Danke es funktioniert. Ich habe die @OneToMany jetzt wie folgt
     
  5. Java online lernen
Passende Stellenanzeigen aus deiner Region:





Die Seite wird geladen...

@OneToMany @JoinTable failed to lazily initialize a collection Fehler - Ähnliche Themen

FetchType.LAZY, Relation @OneToMany und Problem mit dem update
FetchType.LAZY, Relation @OneToMany und Problem mit dem update im Forum Data Tier
OpenJPA, @oneToMany und Probleme
OpenJPA, @oneToMany und Probleme im Forum Datenbankprogrammierung
[Hibernate] @OneToMany - Eine referenzierte Tabelle abfragen
[Hibernate] @OneToMany - Eine referenzierte Tabelle abfragen im Forum Datenbankprogrammierung
@OneToMany Liste Probleme mit Identity Keys
@OneToMany Liste Probleme mit Identity Keys im Forum Data Tier
@OneToMany ohne Fremdschlüssel
@OneToMany ohne Fremdschlüssel im Forum Data Tier
Thema: @OneToMany @JoinTable failed to lazily initialize a collection Fehler