简体   繁体   中英

Spring JPA updating ManyToMany relations/link_table with very large child datasets

We have objects that could potentially have a ManyToMany relationship with hundreds or thousands of addresses and are looking for a way to efficiently model this in our database using Spring JPA. Right now, we have something like this:

DB Tables:

coupon:
couponId
...

address:
addressId
address
city
...

coupon_address:
businessId
addressId

Entities:

Coupon.java

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

...  

@ManyToMany(fetch = FetchType.LAZY)  
@JoinTable(name="coupon_address", joinColumns = {  
    @JoinColumn(name="couponId") }, inverseJoinColumns={  
    @JoinColumn(name="addressId") })  
private Collection<Address> addresses;  

Address.java

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

We have a stored procedure that will return the nearest addresses, which works fine.

Questions:

  • When we update details of a Coupon, we don't want to have to populate the Coupon object with all addresses prior to saving to database. If we don't do this though, the address relations are removed from the link table. Is there a way to save the Coupon without affecting the link table?

  • Is there a way to populate entries in the link table without having save the associated Coupon with the entire set of Addresses?

  • When we query for nearest Addresses, we only want the resultant addresses to be populated in the Coupon object for the client. Since we are using LAZY fetching the Coupons, we can probably avoid calling Coupon.getAddresses and populate the subset of Addresses manually.

I don't know how to handle issue #1 and not sure if #2 is sufficient. Most of the time, we won't have to worry about having a ton of addresses for each Coupon, but the potential does exist.

Thank You.

  1. That's because you're not updating a coupon. Updating a coupon would consist in doing

     Coupon c = em.find(Coupon.class, id); c.setXxx(...); 

    Just do that to update your coupon, instead of merging a new coupon without any address.

  2. No, with your current design, that's not possible. The only way you can modify the content of the join table is by modifying the content of the addresses collection. But you could choose to map the join table as an entity instead of using a ManyToMany. Or you could use native queries.
  3. That can't happen. addresses is the collection of addresses of a coupon. Not the addresses found by some query used to load a coupon. If you want a subset of the addresses of a coupon, then execute a query selecting addresses. Not a query selecting coupons.

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