playframework 中的 LazyInitializationException

发布于 2025-01-06 18:30:28 字数 2625 浏览 0 评论 0原文

在为使用 playframework 的网络应用程序编写功能测试时,我创建了

@Before
public void setup() {
    Fixtures.deleteDatabase();
}
@Test
public void testListTagged() {
    Fixtures.loadModels("data.yml");
    Response response = GET("/books/category/science");
    assertNotNull(renderArgs("books"));
    List<Book> books = (List<Book>)renderArgs("books");
    assertEquals(3,books.size());

listTagged 方法检查地图对象的 Cache (String:List)包含属于给定类别的书籍列表,如果地图为空或列表为空,则进行数据库查询并将列表呈现为“书籍”。

public static void listTagged(String category) {
        List<Book> books =null;
        Map<String,List<Book>> tagMap = (Map<String, List<Book>>) Cache.get("tagmap");
        if(tagMap!= null) {
            books = tagMap.get(category);           
        }

        if(tagMap==null || books == null) { 
            books= Book.findTaggedWith(category);
        }
        Book book = null;
        if (books!=null && books.size()>0) {
            book = books.get(0);
        }        
        render(category,book, books);
    }

Book 类

@Entity
public class Book extends Model implements Comparable<Book>{
    @Required
    @Column(unique = true)
    public String isbn;

    @Required
    //@Field
    public String name;
        ...
    @ManyToMany(cascade=CascadeType.PERSIST)
    public Set<Category> categories;
    public Book(String isbn, String name, ...) {
        super();

        this.isbn = isbn;
        this.name = name;
        ...
        this.categories = new TreeSet<Category>();
    }
        ...
public static List<Book> findTaggedWith(String categoryName) {
        Map<String,List<Book>> tagMap = (Map<String, List<Book>>) Cache.get("tagmap");
        if(tagMap==null) {
            tagMap= new HashMap<String,List<Book>>();
        }
        List<Book> books = Book.find("select distinct book from Book book join book.categories as cat where cat.name=:name").bind("name", categoryName).fetch();
        tagMap.put(categoryName, books);
        Cache.add("tagmap", tagMap,"20mn");
        return books;
    }

单独运行上述测试没有造成任何问题。但是当它与一些调用各种书籍的数据库的单元测试一起运行时,会导致延迟初始化异常,

A java.lang.RuntimeException has been caught, java.util.concurrent.ExecutionException: play.exceptions.TemplateExecutionException: failed to lazily initialize a collection of role: models.Book.categories, no session or session was closed

我该如何解决这个问题?有人可以建议吗?

while coding the Functional Test for my web app which uses playframework,I created

@Before
public void setup() {
    Fixtures.deleteDatabase();
}
@Test
public void testListTagged() {
    Fixtures.loadModels("data.yml");
    Response response = GET("/books/category/science");
    assertNotNull(renderArgs("books"));
    List<Book> books = (List<Book>)renderArgs("books");
    assertEquals(3,books.size());

the listTagged method checks the Cache for a map object (String:List<Book>)that contains a list of books belonging to the given category, and if the map is null or the list is null,database query is made and the list is rendered as 'books'.

public static void listTagged(String category) {
        List<Book> books =null;
        Map<String,List<Book>> tagMap = (Map<String, List<Book>>) Cache.get("tagmap");
        if(tagMap!= null) {
            books = tagMap.get(category);           
        }

        if(tagMap==null || books == null) { 
            books= Book.findTaggedWith(category);
        }
        Book book = null;
        if (books!=null && books.size()>0) {
            book = books.get(0);
        }        
        render(category,book, books);
    }

Book class is

@Entity
public class Book extends Model implements Comparable<Book>{
    @Required
    @Column(unique = true)
    public String isbn;

    @Required
    //@Field
    public String name;
        ...
    @ManyToMany(cascade=CascadeType.PERSIST)
    public Set<Category> categories;
    public Book(String isbn, String name, ...) {
        super();

        this.isbn = isbn;
        this.name = name;
        ...
        this.categories = new TreeSet<Category>();
    }
        ...
public static List<Book> findTaggedWith(String categoryName) {
        Map<String,List<Book>> tagMap = (Map<String, List<Book>>) Cache.get("tagmap");
        if(tagMap==null) {
            tagMap= new HashMap<String,List<Book>>();
        }
        List<Book> books = Book.find("select distinct book from Book book join book.categories as cat where cat.name=:name").bind("name", categoryName).fetch();
        tagMap.put(categoryName, books);
        Cache.add("tagmap", tagMap,"20mn");
        return books;
    }

Running the above test alone caused no problems.But when it was run along with some unit tests which called the database for various books causes a lazy initialization exception

A java.lang.RuntimeException has been caught, java.util.concurrent.ExecutionException: play.exceptions.TemplateExecutionException: failed to lazily initialize a collection of role: models.Book.categories, no session or session was closed

How do I solve this? can someone please advise?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷血 2025-01-13 18:30:28

你可以使用:

@ManyToMany(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
public Set<Category> categories;

这可能会解决问题。否则,您必须注意会话是否已打开。已测试并正在工作

you could use:

@ManyToMany(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
public Set<Category> categories;

This will probably solve the problem. Otherwise you'll have to take care, that a session is open. Tested and now working

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文