简体   繁体   中英

JPA @OneToMany & @ManyToOne null

I have a problem with ManyToOne relation.

These are my entities:

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;

import java.io.Serializable;
import java.time.ZonedDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;

/**
 * A Product.
 */
@Entity
@Table(name = "product")
public class Product implements Serializable {


    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JsonIgnoreProperties("")
    private Supplier supplier;

    @ManyToOne
    @JsonIgnoreProperties("")
    private Tax tax;

    @OneToMany(mappedBy = "product")
    private Set<Combination> combinations = new HashSet<>();

    @OneToMany(mappedBy = "product")
    private Set<ProductImages> images = new HashSet<>();

    @OneToMany(mappedBy = "product")
    private Set<ProductTranslate> translates = new HashSet<>();

    @ManyToMany(mappedBy = "productIds")
    @JsonIgnore
    private Set<Category> categoryIds = new HashSet<>();


    public Long getId() {
        return id;
    }

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



    public Supplier getSupplier() {
        return supplier;
    }

    public Product supplier(Supplier supplier) {
        this.supplier = supplier;
        return this;
    }

    public void setSupplier(Supplier supplier) {
        this.supplier = supplier;
    }

    public Tax getTax() {
        return tax;
    }

    public Product tax(Tax tax) {
        this.tax = tax;
        return this;
    }

    public void setTax(Tax tax) {
        this.tax = tax;
    }

    public Set<Combination> getCombinations() {
        return combinations;
    }

    public Product combinations(Set<Combination> combinations) {
        this.combinations = combinations;
        return this;
    }

    public Product addCombinations(Combination combination) {
        this.combinations.add(combination);
        combination.setProduct(this);
        return this;
    }

    public Product removeCombinations(Combination combination) {
        this.combinations.remove(combination);
        combination.setProduct(null);
        return this;
    }

    public void setCombinations(Set<Combination> combinations) {
        this.combinations = combinations;
    }

    public Set<ProductImages> getImages() {
        return images;
    }

    public Product images(Set<ProductImages> productImages) {
        this.images = productImages;
        return this;
    }

    public Product addImages(ProductImages productImages) {
        this.images.add(productImages);
        productImages.setProduct(this);
        return this;
    }

    public Product removeImages(ProductImages productImages) {
        this.images.remove(productImages);
        productImages.setProduct(null);
        return this;
    }

    public void setImages(Set<ProductImages> productImages) {
        this.images = productImages;
    }

    public Set<ProductTranslate> getTranslates() {
        return translates;
    }

    public Product translates(Set<ProductTranslate> productTranslates) {
        this.translates = productTranslates;
        return this;
    }

    public Product addTranslates(ProductTranslate productTranslate) {
        this.translates.add(productTranslate);
        productTranslate.setProduct(this);
        return this;
    }

    public Product removeTranslates(ProductTranslate productTranslate) {
        this.translates.remove(productTranslate);
        productTranslate.setProduct(null);
        return this;
    }

    public void setTranslates(Set<ProductTranslate> productTranslates) {
        this.translates = productTranslates;
    }

    public Set<Category> getCategoryIds() {
        return categoryIds;
    }

    public Product categoryIds(Set<Category> categories) {
        this.categoryIds = categories;
        return this;
    }

    public Product addCategoryId(Category category) {
        this.categoryIds.add(category);
        category.getProductIds().add(this);
        return this;
    }

    public Product removeCategoryId(Category category) {
        this.categoryIds.remove(category);
        category.getProductIds().remove(this);
        return this;
    }

    public void setCategoryIds(Set<Category> categories) {
        this.categoryIds = categories;
    }

}

And:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.*;

import java.io.Serializable;
import java.util.Objects;

/**
 * A ProductImages.
 */
@Entity
@Table(name = "product_images")
public class ProductImages implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "is_default")
    private Boolean isDefault;

    @Column(name = "url")
    private String url;

    @ManyToOne
    @JsonIgnoreProperties("images")
    private Product product;


    public Long getId() {
        return id;
    }

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

    public Boolean isIsDefault() {
        return isDefault;
    }

    public ProductImages isDefault(Boolean isDefault) {
        this.isDefault = isDefault;
        return this;
    }

    public void setIsDefault(Boolean isDefault) {
        this.isDefault = isDefault;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public ProductImages url(String url) {
        this.url = url;
        return this;
    }

    public Product getProduct() {
        return product;
    }

    public ProductImages product(Product product) {
        this.product = product;
        return this;
    }

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

Now when I try to send get all products request I expect to get all images also. But I get null.

Here is my repository:

@Repository
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {

    @Query(value = "SELECT p FROM " +
        "Product p WHERE p.insertDate > ?1 ORDER BY p.insertDate DESC")
    Page<Product> findFeatured(ZonedDateTime inserDate, Pageable pageable);
}

In my database table have records:

ID, price, stock, manifacture_id, supplier_id, tax_id, weight, weight_unit, width, height, depth, lenght_unit, status, insert_date, priority
'1', '12.10', '10', '1', NULL, NULL, '2', 'KG', '22.1', '12.4', '3', 'CM', 'ACTIVE', '2018-08-01 00:00:00', '0'

Product Images table:

ID, product_id, is_default, url
1, 1, 0, dfsdfsdfs
2, 1, 0, jghjjggj

I did everything but can't found solution.

When I check sql on request:

Hibernate: select product0_.id as id1_10_0_, product0_.depth as depth2_10_0_, product0_.height as height3_10_0_, product0_.insert_date as insert_d4_10_0_, product0_.lenght_unit as lenght_u5_10_0_, product0_.manifacture_id as manifact6_10_0_, product0_.price as price7_10_0_, product0_.priority as priority8_10_0_, product0_.status as status9_10_0_, product0_.stock as stock10_10_0_, product0_.supplier_id as supplie14_10_0_, product0_.tax_id as tax_id15_10_0_, product0_.weight as weight11_10_0_, product0_.weight_unit as weight_12_10_0_, product0_.width as width13_10_0_, supplier1_.id as id1_13_1_, supplier1_.about as about2_13_1_, supplier1_.birthdate as birthdat3_13_1_, supplier1_.email as email4_13_1_, supplier1_.name as name5_13_1_, supplier1_.overall_raiting as overall_6_13_1_, supplier1_.password as password7_13_1_, supplier1_.status as status8_13_1_, supplier1_.surname as surname9_13_1_, tax2_.id as id1_15_2_, tax2_.is_active as is_activ2_15_2_, tax2_.name as name3_15_2_, tax2_.percentage as percenta4_15_2_ from product product0_ left outer join supplier supplier1_ on product0_.supplier_id=supplier1_.id left outer join tax tax2_ on product0_.tax_id=tax2_.id where product0_.id=?

Here is the result:

{
  "id": 1,
  "price": 12.1,
  "stock": 10,
  "manifactureId": 1,
  "weight": 2,
  "weightUnit": "KG",
  "width": 22.1,
  "height": 12.4,
  "depth": 3,
  "lenghtUnit": "CM",
  "status": "ACTIVE",
  "insertDate": "2018-08-01T00:00:00+04:00",
  "priority": 0,
  "supplier": null,
  "tax": null,
  "combinations": null,
  "images": null,
  "translates": null
}

Do anyone have any idea?

Default value for fetchType in @OneToMany is FetchType.LAZY .

make it EAGER fetch.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "product")

You'll find one join in the query for picking images.

@OneToMany

// If your result need images,you can call getImages()
// Product your get
product.getImages()

Then the getting images Sql will be executed.

If your result don't need images,you don't call getImages()

If using fetch = FetchType.EAGER ,your result always has images in product.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM