hibernate中双向关系的问题

时间:2016-06-23 03:53:34

标签: java hibernate jpa

我有两个实体:Sale和SaleProduct。

我正在尝试坚持销售实体,但我不知道如何为它提供服务,因为我总是尝试保存销售,需要SaleProduct。

这是销售实体:

select c.location_id as id_gudang, c.location_name as nama_gudang, a.item_code as id_barang, a.item_name as nama_barang, sum(b.item_qty) as qty
from t_inventory as a
join t_inventory_transaction as b on a.item_id = b.item_id
join t_site_location as c on b.whse_id = c.location_id
group by a.item_code
having qty < 0

这是SaleProduct实体:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Sale {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    @NotNull(message = "Sale product!")
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "SALE_ID")
    private List<SaleProduct> products;

    @NotNull(message = "Sale needs some value!")
    private int saleValue;

    private Date creationDate = new Date();

}

我试图用这种方法坚持销售:

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class SaleProduct {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private long id;

    private int quantity;

    @NotNull(message = "Insert the product, please")
    @ManyToOne(fetch = FetchType.EAGER)
    private Product product;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Sale sale;

}

我发送此JSON:

    public void insertSale(Sale sale) throws Exception {
        Product product = manager.find(Product.class, 2L);
        SaleProduct saleProduct = new SaleProduct();
        saleProduct.setProduct(product);
        sale.setProducts(Arrays.asList(saleProduct));
        saleProduct.setSale(sale);
        manager.persist(sale);
    }

当我尝试选择我创建的销售时,我会收到以下错误:

{
    "saleValue" : "200"
}

还有一个问题:当我Caused by: com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.tax.entity.Sale.products, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.tax.entity.Sale["products"]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:177) at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:190) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:674) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContentsUsing(CollectionSerializer.java:160) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:102) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:94) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:251) at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:846) at org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:207) at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:131) at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:60) at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:120) at org.jboss.resteasy.security.doseta.DigitalSigningInterceptor.aroundWriteTo(DigitalSigningInterceptor.java:145) at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124) at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:100) at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:124) at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:98) at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:466) ... 33 more Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.tax.entity.Sale.products, could not initialize proxy - no Session at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:567) at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:205) at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:146) at org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:261) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:88) at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:24) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:666) ... 50 more 时,我收到此异常:com.sun.jdi.InvocationException发生了调用方法

3 个答案:

答案 0 :(得分:0)

为了实现双向映射,您必须在OneToMany批注中具有“mappedBy”属性

在实体销售中使用

@OneToMany(mappedBy="product", cascade=cascadeType.ALL, fetch=fetchType.LAZY)

答案 1 :(得分:0)

  1. @JoinColumn注释必须位于关联方面,即它应位于@ManyToOne注释上:

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "SALE_ID")
    private Sale sale;
    
  2. mappedBy属性必须放在反面,即使用@OneToMany注释的地方:

    @OneToMany(mappedBy="sale" cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<SaleProduct> products;
    
  3. 创建Sale的实例,说sale

  4. 创建SaleProduct的实例,说saleProduct

  5. saleProduct添加到列表products中。 (我不知道为什么你将列表命名为products,即使它包含SaleProduct s)。

  6. sale分配给saleProductsaleProduct.setSale(sale)。现在两个实体实例都连接在一起。

  7. 最后坚持:entityManager.persist(sale);

答案 2 :(得分:0)

正如例外所说

No validator could be found for constraint 'javax.validation.constraints.Size' validating type 'com.tax.entity.Product'. Check configuration for 'product'

请从字段&#34; 产品&#34;中删除@Size因为它不是一个收集领域。你可以把它放在关系"Sale.products"

的另一边