如何使用休眠

时间:2017-03-22 16:57:26

标签: java php hibernate laravel

我需要加入四张桌子。这四个表是:

  1. 产品
  2. 服务
  3. SERVICE_TYPE
  4. service_duration
  5. 产品有服务,服务有类型和持续时间。

    用户选择产品,类型,服务和服务的持续时间。

    如果服务不适用于所选类型和持续时间,我希望能够获得具有较低优先级类型的服务(优先级是service_type表中的属性)。

    在php(Laravel)中,我可以这样加入:

    DB::table('product')
            ->join('product_service', 'product_service.product_id', '=', 'product.id')
            ->join('service', 'service.id', '=', 'product_service.service_id')
            ->join('service_type', 'service.type_id', '=', 'service_type.id')
            ->join('service_duration', 'service.duration_id', '=', 'service_duration.id')
            ->where('product.id', id)
            ->where('service_type.priority', '<', priority)
            ->where('service_duration.duration', duration)
            ->where('maintenance.active', 1)
            ->orderBy('service_type.priority', 'desc')
            ->select('service.*')
            ->first();
    

    如何使用Hibernate Entity Criteria执行此操作?我想从产品方面加入,但最后选择服务。

    我的关系定义如下:

    产品类

     @Entity
     @Table(name = "product")
     public class product implements Serializable {
            @OneToMany(fetch = FetchType.LAZY, mappedBy = "id.product", cascade=CascadeType.ALL)
            private Set<ProductService> services = new HashSet<ProductService>();
      }
    

    ProductService类:

    @Entity
    @Table(name = "product_service")
    @AssociationOverrides({ @AssociationOverride(name = "id.service", joinColumns = @JoinColumn(name = "service_id")),
            @AssociationOverride(name = "id.product", joinColumns = @JoinColumn(name = "product_id"))})
    
    public class ProductService  implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @EmbeddedId
        private ProductServicePK id = new ProductServicePK();
    
    
        @Column(name = "price")
        private Float price;
    
        @Column(name = "code")
        private String code;
    }
    

    ProductServicePK类:

    @Embeddable
    public class ProductServicePK implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @ManyToOne
        private Product product;
    
        @ManyToOne
        private Service service;
    }
    

    服务类:

       @Entity
    @Table(name = "service")
    public class Service implements Serializable {
    
        @Id
        @Column(name = "id")
        private Long id;
    
        @OneToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "type_id")
        private ServiceType type;
    
        @OneToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "duration_id")
        private ServiceDuration duration;
    }
    

    因此,“保持”引用另一个的对象是产品对象。因此,我不确定如何获得优先级低于所选产品的产品服务。

    我想用条件或HQL来做这件事。

2 个答案:

答案 0 :(得分:1)

你的Hibernate Detached Criteria会喜欢:

DetachedCriteria criteria = DetachedCriteria.forClass(Product.class,     "product")
    .criteria.createAlias("product.product_service", "productService")
    .createAlias("productService.service","service")
    .createAlias("service.service_type","serviceType")
    .createAlias("service_duration","serviceDuration")
    .add(Restrictions.eq("product.id", id))
    .add(Restrictions.gt("serviceType.priority", priority))
    .add(Restrictions.eq("serviceDuration.duration", duration))
    .setProjection(add your productService projection here)
    getExecutableCriteria(session).SetMaxResults(1) ;

但我不明白你的意思,为什么你在from query使用product代替product_service?,因为你需要product_service个详细信息。

您可以使用querycriteria.html,这是doc的文档 - &gt; https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html 或者您可以使用hql - &gt; https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html来获得结果。

答案 1 :(得分:0)

显然,JPA Criteria API不支持使用复合PK模式时所需的内容。我发现这提到here。所以我发现最好的解决方案是使用HQL:

Query q = session.createQuery("select s "
            + "from Service s "
            + "join s.productService as ps "
            + "join s.type as t "
            + "where s.duration = :durationId "
            + "and ps.id.product.id = :productId "
            + "and t.priority <= :priorityValue "
            + "order by t.priority desc");
    q.setLong("durationId", durationId);
    q.setInteger("priorityValue", priorityValue);
    q.setLong("productId", productId);

    return (Service) q.setMaxResults(1).uniqueResult();