2016-10-09 6 views
0

У меня есть 3 лица (товары, поставщики и Цены), где цены связана с другим 2. Продукта может иметь несколько цен, одна цены за поставщик: enter image description hereJava JPA Hibernate - Ошибка: зацикливание

продукта класс:

@Entity 
@Table(name = "products") 
public class Product implements java.io.Serializable { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(name = "product_id") 
private int id; 

@Column(name = "product_category") 
private String productCategory; 

@Column(name = "product_subcategory") 
private String productSubcategory; 

@Column(name = "product_name") 
private String productName; 

@Column(name = "product_description") 
private String productDescription; 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.product", cascade=CascadeType.ALL) 
private Set<Prices_1> prices_1 = new HashSet<Prices_1>(0); 


public Set<Prices_1> getPrices_1(){ 
    return prices_1; 
} 

public void setPrices_1(Set<Prices_1> prices_1){ 
    this.prices_1 = prices_1; 
} 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getProductCategory() { 
    return productCategory; 
} 

public void setProductCategory(String productCategory) { 
    this.productCategory = productCategory; 
} 

public String getProductSubcategory() { 
    return productSubcategory; 
} 

public void setProductSubcategory(String productSubcategory) { 
    this.productSubcategory = productSubcategory; 
} 

public String getProductName() { 
    return productName; 
} 

public void setProductName(String productName) { 
    this.productName = productName; 
} 

public String getProductDescription() { 
    return productDescription; 
} 

public void setProductDescription(String productDescription) { 
    this.productDescription = productDescription; 
} 

@Override 
public String toString() { 
    return "ProductController [id=" + id + ", productName=" + productName 
      + ", productCategory=" + productCategory + ", productSubcategory=" + productSubcategory 
      + ", productDescription=" + productDescription 
      + "]"; 
} 

} 

Средний класс:

@Entity 
@Table(name="providers") 
public class Provider implements java.io.Serializable { 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(name="provider_id") 
private int id; 

@Column(name="provider_name") 
private String providerName; 

@Column(name="provider_address") 
private String providerAddress; 

@Column(name="provider_phone") 
private String providerPhone; 

@Column(name="provider_archived") 
private int providerArchived = 0; 

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.provider") 
private Set<Prices_1> prices_1 = new HashSet<Prices_1>(0); 

public Set<Prices_1> getPrices_1() { 
    return prices_1; 
} 

public void setPrices_1(Set<Prices_1> prices_1) { 
    this.prices_1 = prices_1; 
} 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

public String getProviderName() { 
    return providerName; 
} 

public void setProviderName(String providerName) { 
    this.providerName = providerName; 
} 

public String getProviderAddress() { 
    return providerAddress; 
} 

public void setProviderAddress(String providerAddress) { 
    this.providerAddress = providerAddress; 
} 

public String getProviderPhone() { 
    return providerPhone; 
} 

public void setProviderPhone(String providerPhone) { 
    this.providerPhone = providerPhone; 
} 

public int getProviderArchived() { 
    return providerArchived; 
} 

public void setProviderArchived(int providerArchived) { 
    this.providerArchived = providerArchived; 
} 

@Override 
public String toString() { 
    return "ProviderController [id=" + id + ", providerName=" + providerName 
      + ", providerAddress=" + providerAddress + ", providerPhone=" 
      + providerPhone + "]"; 
} 

} 

Prices_1 класс:

@Entity 
@Table(name = "prices_1") 
@AssociationOverrides({ 
    @AssociationOverride(name = "pk.product", 
      joinColumns = @JoinColumn(name = "product_id")), 
    @AssociationOverride(name = "pk.provider", 
      joinColumns = @JoinColumn(name = "provider_id"))}) 
public class Prices_1 implements java.io.Serializable { 

@EmbeddedId 
private PricesId pk = new PricesId(); 

@Column(name = "price") 
private float price; 

public PricesId getPk() { 
    return pk; 
} 

public void setPk(PricesId pk) { 
    this.pk = pk; 
} 

public float getPrice() { 
    return price; 
} 

public void setPrice(float price) { 
    this.price = price; 
} 

@Transient 
public Product getProduct() { 
    return getPk().getProduct(); 
} 

public void setProduct(Product product) { 
    getPk().setProduct(product); 
} 

@Transient 
public Provider getProvider() { 
    return getPk().getProvider(); 
} 

public void setProvider(Provider provider) { 
    getPk().setProvider(provider); 
} 


public boolean equals(Object o) { 
    if (this == o) 
     return true; 
    if (o == null || getClass() != o.getClass()) 
     return false; 

    Prices_1 that = (Prices_1) o; 

    if (getPk() != null ? !getPk().equals(that.getPk()) 
      : that.getPk() != null) 
     return false; 

    return true; 
} 

public int hashCode() { 
    return (getPk() != null ? getPk().hashCode() : 0); 
} 

} 

PricesID класс:

@Embeddable 
public class PricesId implements java.io.Serializable { 

@ManyToOne 
private Product product; 

@ManyToOne 
private Provider provider; 

public Product getProduct() { 
    return product; 
} 

public void setProduct(Product product) { 
    this.product = product; 
} 

public Provider getProvider() { 
    return provider; 
} 

public void setProvider(Provider provider) { 
    this.provider = provider; 
} 

public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    PricesId that = (PricesId) o; 

    if (product != null ? !product.equals(that.product) : that.product != null) return false; 
    if (provider != null ? !provider.equals(that.provider) : that.provider != null) return false; 

    return true; 
} 

public int hashCode() { 
    int result; 
    result = (product != null ? product.hashCode() : 0); 
    result = 31 * result + (provider != null ? provider.hashCode() : 0); 
    return result; 
} 

} 

ProductsRepository класс:

@Repository 
public class ProductsRepository { 

@PersistenceContext 
EntityManager em; 

public List<Product> findAllProducts(){ 
    Query query = em.createQuery("SELECT e FROM Product e"); 
    return (List<Product>) query.getResultList(); 
} 

} 

ProductsService класс:

@Service 
public class ProductsService { 

@Autowired 
ProductsRepository productsRepository; 

@Transactional(readOnly = true) 
public List<Product> findAllProducts(){ 
    List<Product> pv = productsRepository.findAllProducts(); 
    return pv; 
} 

} 

ProductsController класс:

@Controller 
@RequestMapping("product") 
public class ProductController { 

@Autowired 
private ProductsService productsService; 

@ResponseBody 
@ResponseStatus(HttpStatus.OK) 
@RequestMapping(method = RequestMethod.GET) 
public List<Product> getProducts(){ 
    List<Product> productList = productsService.findAllProducts(); 
    for (Product p : productList){ 
     System.out.println("Andres. Provider name: " + p.getProductName()); 
    } 
    return productList; 
} 
} 

ArrayList ProductList возвращается контроллером: enter image description here

Проблема заключается в том, что продукты [0] имеет 2 Prices_1. Цены_1 [0] связали Продукт и Поставщик, и оба связали Цены_1 и т. Д. Заканчиваются в бесконечном цикле

Любые идеи, как я могу получить следующий объект: Список продуктов, каждый продукт со списком от цены, по одной цене за поставщика.

Спасибо!

EDIT: Проблема не с ArrayList ProductList создается, ошибка запуска, когда этот объект ProductList возвращается в браузер:

enter image description here

+0

Как вы вернуть его в браузере? Это может быть связано с тем, что когда он преобразуется в json, вызывается метод toString(), который пытается сериализовать продукт и поставщика, определенные внутри цен_1. Попытайтесь определить продукт и поставщика как временные внутри класса priceid. –

+0

Большое спасибо за ваш быстрый ответ @PushpendraPal. Я и возвращаюсь в браузер «return productList»; (список товаров ArrayList).Я добавил «@Transient» для обоих объектов Product и Provider в PriceId.java, но приложение не запускается: «PriceId не имеет постоянного свойства id: .... model.Prices_1.pk». Автосериализация была моей первой проблемой, поэтому я переопределяю все методы toString() (Producs, Providers and Prices_1). –

+0

hmm ... Я думаю, что переопределение toString() на продукт и провайдеры не будет работать, когда вы возвращаете productList, то будет вызываться toString() в списке (java.util.List ваших продуктов). который не переопределен и будет по-прежнему искать сериализацию всех объектов внутри вашего списка .... Также я заметил, что toString не является избыточным для цен_1 ..... –

ответ

0
public class GenericClass<E> implements List<E> { 

private List<E> list; 
public GenericClass() { 
    this.list = new ArrayList<>(); 
} 


@Override 
public String toString() { 
    StringBuilder s = new StringBuilder(); 
    for (E e : list) { 
     s.append(e.toString()); 
    } 
    return s.toString(); 
} 

@Override 
public boolean add(E e) { 

    return list.add(e); 
} 

@Override 
public boolean addAll(Collection<? extends E> c) { 

    return list.addAll(c); 
} 

}

0

Я создал 3 объекта Data Tansfer для настройки и записи списка продуктов:

public class ProductsDTO { 

private List<ProductDTO> productDTOSet = new ArrayList<ProductDTO>(0); 

public ProductsDTO(List<ProductDTO> productDTOSet) { 
    this.productDTOSet = productDTOSet; 
} 

public static ProductsDTO mapFromProductSetEntity(List<Product> products){ 
    List<ProductDTO> productDTOs = new ArrayList<ProductDTO>(0); 
    for (Product p : products) { 
     productDTOs.add(ProductDTO.mapFromProductEntity(p)); 
    } 
    return new ProductsDTO(productDTOs); 
} 

public class ProductDTO { 

private int id; 
private String productCategory; 
private String productSubcategory; 
private String productName; 
private String productDescription; 
private Set<PriceDTO> prices = new HashSet<PriceDTO>(0); 


public ProductDTO(int id, String productCategory, String productSubcategory, String productName, 
        String productDescription, Set<PriceDTO> prices) { 
    this.id = id; 
    this.productCategory = productCategory; 
    this.productSubcategory = productSubcategory; 
    this.productName = productName; 
    this.productDescription = productDescription; 
    this.prices = prices; 
} 

public static ProductDTO mapFromProductEntity(Product product){ 

    Set<PriceDTO> priceDTOs = new HashSet<PriceDTO>(0); 
    for (Prices_1 p1 : product.getPrices_1()){ 
     priceDTOs.add(PriceDTO.mapFromPrice_1Entity(p1)); 
    } 

    return new ProductDTO(product.getId(), product.getProductCategory(), product.getProductSubcategory() 
    , product.getProductName(), product.getProductDescription(), priceDTOs); 
} 
} 

public class PricesDTO { 

private Set<PriceDTO> pricesDTO = new HashSet<PriceDTO>(0); 

public Set<PriceDTO> getPricesDTO() { 
    return pricesDTO; 
} 

public void setPricesDTO(Set<PriceDTO> pricesDTO) { 
    this.pricesDTO = pricesDTO; 
} 
} 

затем отобразить список ProductList к DTOS:

@Controller 
@RequestMapping("product") 
public class ProductController { 

@Autowired 
private ProductsService productsService; 

@ResponseBody 
@ResponseStatus(HttpStatus.OK) 
@RequestMapping(method = RequestMethod.GET) 
public ProductsDTO getProducts(){ 
    List<Product> productList = productsService.findAllProducts(); 
    for (Product p : productList){ 
     System.out.println("Andres. Provider name: " + p.getProductName()); 
    } 

    return ProductsDTO.mapFromProductSetEntity(productList); 
} 
} 

И это результат: enter image description here