简体   繁体   中英

how to get data or query from Many to Many?

I have product and code entities, and I make ManyToMany relationship for them, so it gonna be Product_Code

so the Product_Code will have product_id and product_id

I really want to fetch data from the product by the code, but the result I want it I want detail from product values and code values also, I don't know how to do that on JPA

I was thinking to get the product code first, then find the id product on Product_Code table for that id , and then get data from it and find the id of code again on code entity, i am sure there is way to fetch data for this, but i don't know how, and i do like to get simple way to understand how it works

i am very new here

my entity product something like this

@Entity
@Table(name = "PRODUCT")
@Setter
@Getter
@DynamicUpdate
public class Product extends Base {

    @ManyToMany(mappedBy = "products", fetch = FetchType.EAGER)
    private Set<Code> codes;

    @Column(name = "NAME", nullable = false)
    private String Name;

    @Column(name = "DESCRIPTION")
    private String description;

    public int hasCode() {
        return Objects.hashCode(getId());
    }

} 

and here is my Code entity :

@Entity
@Table(name = "CODE")
@DynamicUpdate
@Setter
@Getter
public class Voucher extends Base {

    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    @JoinTable(name = "PRODUCT_CODE",
               joinColumns =  @JoinColumn(name = "CODE_ID"),
               inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
    private Set<Product> products;

    @Column(name = "CODE", unique = true)
    private String codeName;

    @Column(name = "TYPE", nullable = false)
    private String type;

    private String descriptions;

    public int hasCode() {
            return Objects.hashCode(getId());
        }
}

i really want to get the all of data when i try to find by code let say that i want to find a product with code like "A7", so i want to get from product entity and then i will get the detail code entity also with the product_id and code_id like that product

when i tried to Product findByCode(String code) or Product findOneByCode(String code) the result is the Base entity which i extends not the Product entity , the Base entity is reusable entity like generate id, token, createdAt, deletedAt, updatedAt

This can be achieved using Specification<Product> on JpaSpecificationExecutor<Product> -enabled repository.

  1. Make sure your ProductRepository implements JpaSpecifiactionExecutor<Product>

then, somewhere in your @Service with both VoucherRepository and ProductRepository injected do:

//implement a method in VoucherRepository findByName which returns Voucher instance.
Voucher code = voucherRepository.findByName("A7");

//then pass the instance to isMember function in ProductRepository
List<Product> products = productRepository.findAll((r, q, b) -> b.isMember(code, Product_.codes));

Comments

r, q, b are method parameters for lambda-expression like implementation of Specification<Product> overriding method toPredicate . If your project restricts you using Java version 7 and below, you could implement this object using the following:

Specification<Product> spec = new Specification<Product>() {
        @Override
        public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            return criteriaBuilder.isMember(code, root.get(Product_.codes));
        }
};

Parameters

r stands for root element Root<Product>

q stands for criteria query CriteriaQuery<?>

b stands for criteria builder CriteriaBuilder

Product_.* is a static metamodel for your Product entity. It could be either generated autmatically using JPA model generator or created manually using @Staticmetamodel annotation.

By executing findAll(Specification<Product>) you're making filtering-like select where your result List will contain only the products matching your criteria.

Edit:

Your Product metamodel could look like (for now), but however, I recommend using metamodel generator.

@StaticMetamodel(Product.class)
public class Product_ {
      public static volatile SetAttribute<Product, Code> codes;
}

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