简体   繁体   English

如何从Java Spring中的Hibernate双向OneToMany ManyToOne中检索数据

[英]How to retrieve data from Hibernate bidirectional OneToMany ManyToOne in Java Spring

It really sounds like a easy question but I really cannot find anything useful. 这真的听起来像一个简单的问题,但我真的找不到任何有用的东西。

My question is how can I get DB entries using criteria(or something else) from a bidirectional ManytoOne association? 我的问题是如何使用双向ManytoOne关联中的条件(或其他)获取数据库条目?

So let's say that we have 2 classes. 所以我们说我们有2个班级。

@Entity
@Table(name="tCategory")
public class Category {

    @Id
    @Column(table="tCategory")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int category_id;

    @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy="category")
    private Set<SubCategory> subcategory;

    ..............
    public Set<SubCategory> getSubcategory() {
        return subcategory;
    }
    public void setSubcategory(Set<SubCategory> subcategory) {
        this.subcategory = subcategory;
    }

    public int getCategory_id() {
        return category_id;
    }
    public void setCategory_id(int category_id) {
        this.category_id = category_id;
    }
    ..............
    @Override
    public String toString() {
        return "Category [category_id=" + category_id + ", subcategory=" + subcategory + "]";
    }
}


@Entity
@Table(name="tSubCategory")
public class SubCategory {

    @Id
    @Column(table="tSubCategory")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int subcategory_id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    @JoinColumn(name="category_id")
    private Category category;

    public Category getCategory() {
        return category;
    }

    ........

    public void setCategory(Category category) {
        this.category = category;
    }

    public int getSubcategory_id() {
        return subcategory_id;
    }
    public void setSubcategory_id(int subcategory_id) {
        this.subcategory_id = subcategory_id;
    }

    ........
    @Override
    public String toString() {
        return "Category [category_id=" + category_id + ", subcategory=" + subcategory + "]";
    }
}

As we can see we have for 1 category many subcategories. 正如我们所看到的,我们有1类很多子类别。

The question is how can I get all the subcategories with category_id = 1 ? 问题是如何获得category_id = 1的所有子类别?

schema description 架构描述

What I am trying to do is the following: 我想要做的是以下内容:

public List<SubCategory> getSubCategoriesById(int category_id) {
        Session session = null;
        Transaction tx = null;
        try{
            session = this.sessionFactory.openSession();
            tx = session.beginTransaction();
            List<SubCategory> subcategories;
            Criterion cr = Restrictions.eq("category.category_id",category_id);
            subcategories = session.createCriteria(SubCategory.class).add(cr).list();
            tx.commit();
            return subcategories;
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            session.close();
        }
        return null;
    }

and then on my controller 然后在我的控制器上

@RequestMapping("/loadSubCategories")
    public @ResponseBody List<SubCategory> loadSubCategories(@RequestParam int id) {

        List<SubCategory> subcategories = hierarchyDAO.getSubCategoriesById(id);
        System.out.println(subcategories.get(0));
        return subcategories;
    }

I am getting the following error 我收到以下错误

2017-01-10 23:38:33 DEBUG DispatcherServlet:984 - Could not complete request
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)

I am sure that we are retrieving the category column values seeing the query that hibernate is logging. 我确信我们正在检索hibernate正在记录的查询的类别列值。

Any ideas? 有任何想法吗?

I am adding some info here because I think that the we are getting correctly the info from the DB but there is something wrong with the lazy loading. 我在这里添加一些信息,因为我认为我们正确地从数据库获取信息,但延迟加载有问题。

I changed getSubCategoriesById in this way: 我用这种方式更改了getSubCategoriesById:

    @Override
        public List<SubCategory> getSubCategoriesById(int category_id) {
            Session session = this.sessionFactory.openSession();
            Transaction tx = session.beginTransaction();

            Criterion cr = Restrictions.eq("category.category_id",category_id);
            List<SubCategory> subcategories = session.createCriteria(SubCategory.class).add(cr).list();
            tx.commit();
            session.close();

            return subcategories;
        }

and I am tried to log the results on controller.

@RequestMapping(value="/loadSubCategories", produces = "application/json")
    public @ResponseBody List<SubCategory> loadSubCategories(@RequestParam int id) {
        System.out.println("->apo get" + id);

        List<SubCategory> subcategories = hierarchyDAO.getSubCategoriesById(id);
        System.out.println("size: " + subcategories.size());

        int i = 0;
        while (i < subcategories.size()) {
            System.out.println("category name " + subcategories.get(i).getCategory().getName());
            System.out.println("subcategory name " + subcategories.get(i).getName());
            System.out.println("subcategory details " + subcategories.get(i).getDetails());
            i++;
        }

        return subcategories;
    }

here is the logging: 这是日志记录:

2017-01-11 19:11:16 DEBUG LogicalConnectionImpl:264 - Released JDBC connection
size: 3
category name Clothing
subcategory name Fixes
subcategory details clothes fixes
category name Clothing
subcategory name Other
subcategory details Not
category name Clothing
subcategory name Other
subcategory details Not listed
2017-01-11 19:11:16 DEBUG ExceptionHandlerExceptionResolver:134 - Resolving exception from handler [public java.util.List<contacts.resources.SubCategory> contacts.controllers.TransactionController.loadSubCategories(int)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"])
2017-01-11 19:11:16 DEBUG ResponseStatusExceptionResolver:134 - Resolving exception from handler [public java.util.List<contacts.resources.SubCategory> contacts.controllers.TransactionController.loadSubCategories(int)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"])
2017-01-11 19:11:16 DEBUG DefaultHandlerExceptionResolver:134 - Resolving exception from handler [public java.util.List<contacts.resources.SubCategory> contacts.controllers.TransactionController.loadSubCategories(int)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: contacts.resources.Category.subcategory, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->contacts.resources.SubCategory["category"]->contacts.resources.Category["subcategory"])
2017-01-11 19:11:16 DEBUG HstsHeaderWriter:130 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@76e1cd21

The strange part here is that I am able to log the info but there is something missing on the JSON mapping. 这里奇怪的部分是我能够记录信息,但JSON映射上缺少一些东西。 It seems like it tries to do : 它似乎试图这样做:

subcategories.get(0).getCategory().getSubcategory().get(0).getName();

Excact files: 精确文件:

public class HierarchyDAOImpl implements HierarchyDAO {

private SessionFactory sessionFactory;

public HierarchyDAOImpl(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

@Override
public List<Category> getAllCategories() {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    List<Category> categories;
    categories = session.createCriteria(Category.class).list();
    tx.commit();
    session.close();
    return categories;
}

@Override
public List<SubCategory> getAllSubCategories() {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    List<SubCategory> subcategories;
    subcategories = session.createCriteria(SubCategory.class).list();
    tx.commit();
    session.close();
    return subcategories;
}

@Override
public Category getCategory(int id) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    Category category = (Category) session.get(Category.class, id);
    tx.commit();
    session.close();
    return category;
}

@Override
public SubCategory getSubCategory(int id) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    SubCategory subcategory = (SubCategory) session.get(SubCategory.class, id);
    tx.commit();
    session.close();
    return subcategory;
}

@Override
public int createCategory(Category category) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.saveOrUpdate(category);
    tx.commit();
    session.close();
    return category.getCategory_id();
}

@Override
public int createSubCategory(SubCategory subcategory) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.saveOrUpdate(subcategory);
    tx.commit();
    session.close();
    return subcategory.getSubcategory_id();
}

@Override
public int deleteCategory(Category category) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.delete(category);
    tx.commit();
    session.close();
    return 1;
}

@Override
public int deleteSubCategory(SubCategory subcategory) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    session.delete(subcategory);
    tx.commit();
    session.close();
    return 1;
}

@Override
public List<SubCategory> getSubCategoriesById(int category_id) {
    Session session = this.sessionFactory.openSession();
    Transaction tx = session.beginTransaction();


    Query query = session.createQuery("from tCategory c inner join fetch c.subcategory where c.category_id = :id");

    List<SubCategory> subcategories = query.setParameter("id", category_id).list();
    tx.commit();
    session.close();

    return subcategories;
}

} }

@Entity

@Table(name="tCategory") public class Category { @Table(name =“tCategory”)公共类别{

@Id
@Column(table="tCategory")
@GeneratedValue(strategy = GenerationType.AUTO)
private int category_id;
@Column(table="tCategory")
private String name;
@Column(table="tCategory")
private int sort;
@Column(table="tCategory")
private String color;
@Column(table="tCategory")
private int icon_id;
@Column(table="tCategory")
private String details;
@OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy="category")
private List<SubCategory> subcategory;

public int getCategory_id() {
    return category_id;
}
public void setCategory_id(int category_id) {
    this.category_id = category_id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getSort() {
    return sort;
}
public void setSort(int sort) {
    this.sort = sort;
}
public String getColor() {
    return color;
}
public void setColor(String color) {
    this.color = color;
}
public int getIcon_id() {
    return icon_id;
}
public void setIcon_id(int icon_id) {
    this.icon_id = icon_id;
}
public String getDetails() {
    return details;
}
public void setDetails(String details) {
    this.details = details;
}

public List<SubCategory> getSubcategory() {
    return subcategory;
}
public void setSubcategory(List<SubCategory> subcategory) {
    this.subcategory = subcategory;
}
@Override
public String toString() {
    return "Category [category_id=" + category_id + ", name=" + name + ", sort=" + sort + ", color=" + color
            + ", icon_id=" + icon_id + ", details=" + details + ", subcategory=" + subcategory + "]";
}

} }

@Entity

@Table(name="tSubCategory") public class SubCategory { @Table(name =“tSubCategory”)公共类SubCategory {

@Id
@Column(table="tSubCategory")
@GeneratedValue(strategy = GenerationType.AUTO)
private int subcategory_id;
@Column(table="tSubCategory")
private String name;
@Column(table="tSubCategory")
private int sort;
@Column(table="tSubCategory")
private String color;
@Column(table="tSubCategory")
private int icon_id;
@Column(table="tSubCategory")
private String details;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="category_id")
private Category category;

public int getSubcategory_id() {
    return subcategory_id;
}
public void setSubcategory_id(int subcategory_id) {
    this.subcategory_id = subcategory_id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public int getSort() {
    return sort;
}
public void setSort(int sort) {
    this.sort = sort;
}
public String getColor() {
    return color;
}
public void setColor(String color) {
    this.color = color;
}
public int getIcon_id() {
    return icon_id;
}
public void setIcon_id(int icon_id) {
    this.icon_id = icon_id;
}
public String getDetails() {
    return details;
}
public void setDetails(String details) {
    this.details = details;
}
public Category getCategory() {
    return category;
}
public void setCategory(Category category) {
    this.category = category;
}
@Override
public String toString() {
    return "SubCategory [subcategory_id=" + subcategory_id + ", name=" + name + ", sort=" + sort + ", color="
            + color + ", icon_id=" + icon_id + ", details=" + details + ", category=" + category + "]";
}

} }

You could easily perform this using Hibernate Query Language using the following query. 您可以使用以下查询使用Hibernate查询语言轻松执行此操作。

Query query = session.createQuery("from Category c inner join fetch c.subCategory where c.category_id := id");

query.setParamter("id", yourId);

This will fetch a category along with all associated sub categories 这将获取一个类别以及所有相关的子类别

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring 数据 JPA - Hibernate - OneToMany,ManytoOne 双向 - Spring Data JPA - Hibernate - OneToMany, ManytoOne bidirectional 春季休息休眠OneToMany / ManyToOne - Spring Rest Hibernate OneToMany / ManyToOne Spring Boot 中 Hibernate/JPA 中的投影以从多个 OneToMany 和 manyToOne 关系中提取数据 - Projection in Hibernate/JPA in Spring Boot to pull data from multiple OneToMany and manyToOne relationships JPA OneToMany,ManyToOne双向 - JPA OneToMany, ManyToOne bidirectional Hibernate 5 Java双向oneToMany字段为空,但表包含数据 - Hibernate 5 Java bidirectional oneToMany field is null but table contains data JPA / Hibernate:双向OneToMany / ManyToOne关系仅适用于单向 - JPA/Hibernate: bidirectional OneToMany/ManyToOne relation only works unidirectional 休眠丢失@OneToMany和@ManyToOne双向关联中的列错误 - Hibernate missing column error in @OneToMany and @ManyToOne bidirectional association 在 Hibernate 双向 ManytoOne, OnetoMany 的映射列中获取空值 - Getting null in mapping column in Hibernate bidirectional ManytoOne , OnetoMany ManyToOne OneToMany 双向:从参考表中检索数据 - ManyToOne OneToMany bi-direction: Retrieve data from reference table Hibernate Spring OneToMany - ManyToOne领域驱动设计 - Hibernate Spring OneToMany - ManyToOne Domain Driven Design
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM