创建一个;在;使用JPA2.0标准api进行查询
我正在使用tje JPA criteria API创建一个“IN”查询。我想选择某些类别的课程。类别应该在查询的in部分结束 这是课程实体。它引用了一个类别实体,因为每个课程都属于一个类别创建一个;在;使用JPA2.0标准api进行查询,jpa,illegalstateexception,Jpa,Illegalstateexception,我正在使用tje JPA criteria API创建一个“IN”查询。我想选择某些类别的课程。类别应该在查询的in部分结束 这是课程实体。它引用了一个类别实体,因为每个课程都属于一个类别 @Entity public class Course implements DomainObject { private Long id; private Integer version; private String name; private Category category; @Overrid
@Entity
public class Course implements DomainObject {
private Long id;
private Integer version;
private String name;
private Category category;
@Override
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
在我的服务中,我想选择属于某些类别(列表)的课程
public List<Course> findCourses(CourseFilter filter) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> criteriaQuery = criteriaBuilder.createQuery(Course.class);
Root<Course> root = criteriaQuery.from(Course.class);
List<Predicate> predicateList = new ArrayList<Predicate>();
if (!filter.getCategories().isEmpty()) {
Predicate predicate = root.get(Course_.category).in(filter.getCategories());
predicateList.add(predicate);
}
Predicate[] predicates = new Predicate[predicateList.size()];
predicateList.toArray(predicates);
criteriaQuery.where(predicates);
TypedQuery<Course> typedQuery = entityManager.createQuery(criteriaQuery);
return typedQuery.getResultList();
}
我甚至不确定我是否使用了正确的方法来创建IN查询。我认为标准API非常复杂。但在我担心IN查询之前,我想知道为什么Hibernate会抛出这个TransientObject异常。filter.getCategories()调用将产生实际类别,并填充主键id等
补充:
下面是如何获取Category实例的,我将使用该实例稍后获取课程。这也是一个DAO方法,通过@Controller方法中的@Service调用
public Category findByName(String name) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Category> query = builder.createQuery(Category.class);
Root<Category> root = query.from(Category.class);
Predicate predicate = builder.equal(root.get(Category_.urlTitle), name);
query.where(predicate);
TypedQuery<Category> typedQuery = entityManager.createQuery(query);
return getSingleResult(typedQuery);
}
公共类别findByName(字符串名称){
CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery=builder.createQuery(Category.class);
Root=query.from(Category.class);
谓词=builder.equal(root.get(Category.urlttitle),name);
where(谓词);
TypedQuery TypedQuery=entityManager.createQuery(查询);
返回getSingleResult(typedQuery);
}
所以,Hibernate告诉我,我使用的类别对象以某种方式引用了一个未保存的实体,但我不知道如何使用。从这个方法返回的类别只是一个类别,如果由Hibernate获取的话。在我将它发送到获取课程的方法之前,我没有对它做任何事情
以下是我的控制器方法:
@RequestMapping(method = RequestMethod.GET, value = "/{categoryUrlName}")
public String setup(@PathVariable("categoryUrlName") String categoryUrlName, Model model){
// Fetch the category
Category category = categoryService.findByName(categoryUrlName);
// if no category found, throw a 404
if(category == null){
throw new ResourceNotFoundException();
}
// Fetch courses in this category
List<Course> courses = courseService.findCourses(category);
model.addAttribute("courses", courses);
model.addAttribute("category", category);
model.addAttribute("mainContent", "content/category");
return "main";
}
@RequestMapping(method=RequestMethod.GET,value=“/{categoryUrlName}”)
公共字符串设置(@PathVariable(“categoryUrlName”)字符串categoryUrlName,模型){
//获取类别
Category Category=categoryService.findByName(categoryUrlName);
//如果没有找到类别,抛出404
如果(类别==null){
抛出新的ResourceNotFoundException();
}
//获取此类别的课程
列出课程=courseService.findCourses(类别);
model.addAttribute(“课程”,课程);
model.addAttribute(“category”,category);
model.addAttribute(“主要内容”、“内容/类别”);
返回“main”;
}
在执行查询之前,Hibernate会刷新您在会话中对持久实体所做的更改。这确保查询将搜索所有实体的最新状态。不幸的是,Hibernate尝试刷新的脏实体之一引用了一个临时实体,因此无法刷新,从而导致异常。异常不是来自查询本身,而是来自执行查询之前的刷新
在执行查询之前,您可能执行了以下操作:
Cat cat = em.find(Cat.class, catId); // cat is a persistent persistent entity
cat.setMate(new Mouse()); // the mouse has not been persisted, and cat references it.
在执行查询之前,Hibernate将刷新您在会话中对持久实体所做的更改。这确保查询将搜索所有实体的最新状态。不幸的是,Hibernate尝试刷新的脏实体之一引用了一个临时实体,因此无法刷新,从而导致异常。异常不是来自查询本身,而是来自执行查询之前的刷新 在执行查询之前,您可能执行了以下操作:
Cat cat = em.find(Cat.class, catId); // cat is a persistent persistent entity
cat.setMate(new Mouse()); // the mouse has not been persisted, and cat references it.
你好,JB。我添加了获取类别的方法和控制器方法。我确实理解“TransientObject”异常,我以前也见过它,但我仍然不明白在这种情况下它是如何发生的。你好,JB。我添加了获取类别的方法和控制器方法。我确实理解“TransientObject”异常,我以前也见过它,但我仍然不理解在这种情况下它是如何发生的。