1

本当に簡単な質問のようですが、何か役に立つものが見つかりません。Hibernateの双方向からデータを取得する方法Java SpringのOneToMany ManyToOne

私の質問は、双方向のManytoOne関連から基準(または他のもの)を使用してDBエントリを取得するにはどうすればよいですか?

ここで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 + "]"; 
    } 
} 

我々が見ることができるように、我々は1つのカテゴリー多くのサブカテゴリを持っています。

質問はcategory_id = 1のすべてのサブカテゴリを取得するにはどうすればよいですか?

schema description

私は何をしようとしていることは以下の通りです:

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; 
    } 

、その後、私のコントローラ上

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

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

私は次のようなエラーに

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) 
を取得しています

私は、ハイバーネイトがロギングしているクエリを見ているカテゴリのカラム値を取得していることを確信しています。

アイデア?

私はDBから情報を正しく取得していると思うので、ここにいくつかの情報を追加しますが、遅延ロードには何か問題があります。

私は、このように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; 
    } 

、ロギングです:

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.se[email protected]76e1cd21 

ここで奇妙な部分は、私は情報を記録することが可能だということですが、上の欠けているものがありますJSONマッピング。

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

Excactファイル:それが何をしようとするように思える パブリッククラスカテゴリを

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(名前= "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(名前= "tSubCategory") パブリッククラスサブカテゴリあなたは簡単に次のクエリを使用してHibernateクエリー言語を使用して、これを行うことができ、{

@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 + "]"; 
} 

}

+0

と一緒にカテゴリを取得します。 'finally { session.close();' –

+0

コントローラーからSubCategory値 を取得できるので、エラーとの相対的なものではないと思います。 subcategories.get(0).getSubcategory_id(); サブカテゴリからカテゴリオブジェクトにアクセスしようとすると問題が発生します。 subcategories.get(0).getCategory(); – LeoK

+0

でなければ、休止状態セッションによって使用されるオブジェクトのライフサイクルを明確にする。 –

答えて

0

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

query.setParamter("id", yourId); 

これは、コレクションを使用している前に、あなたのセッションがクローズされ、関連するすべてのサブカテゴリー

+0

HQLを使用する以外はこれを行う方法が他にあるかどうか疑問です。私はあなたの解決策を試し、私はあなたに知らせるでしょう。 – LeoK

+0

私はこのエラーを取得しています:org.hibernate.hql.internal.ast.QuerySyntaxException:tCategoryは[インナーc.category_id = c.tSubCategoryフェッチ参加cはtCategoryから:ID]がマップされていない例外が言及 – LeoK

+0

ように、これは構文の問題。私はあなたが質問にサブカテゴリのプロパティを入力したと思う。内部継承ではなく、c.subCategoryの代わりにc.subcategoryを取得してください。 – Taf

関連する問題