Reputation: 469
I am trying to use many to many approach product has many to many relation with shop Product.java
package models;
@Entity
public class Product extends Model {
@Id
@SequenceGenerator(name="product_gen", sequenceName="product_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="product_gen")
@Column(name="id")
public Long id;
@Required
public String name;
@Required
public Float price;
@ManyToMany(cascade = CascadeType.ALL)
public List<Shop> shops = new ArrayList<Shop>();
public Product(String name, float price) {
this.name = name;
this.price = price;
}
public static List<Product> all(){
return find.all();
}
public static Model.Finder<Long, Product> find = new Model.Finder(Long.class, Product.class);
public static Product create(String name,float price) {
Product product = new Product(name, price);
product.save();
product.saveManyToManyAssociations("shops");
return product;
}
}
play created a table product_shop which has shop_id and product_id as foreign key but not able to store any value in product_shop table on adding a product any help would be appreciated.
Upvotes: 2
Views: 4176
Reputation: 77
Try looking into an embedded id.
Make a class for your primary key
@Embeddable
public class ProductShopKey {
public Long productId;
public Long shopId;
public boolean equals(Object object) {
if(object isInstanceOf ProductShopKey){
ProductShopKey key = (ProductShopKey) object
if(this.productId == key.productId
&& this.shopId == key.shopId
){
return true;
}
}
return false;
}
public int hashCode() {
return productId.hashCode() + shopId.hashCode();
}
}
Then make an entity for the class
@entity
public class ProductShop {
@EmbeddedId
public ProductShopKey psKey = new ProductShopKey();
@ManyToOne
@JoinColumn(name = "product_id")
public Product product;
@ManyToOne
@JoinColumn(name = "shop_id")
public Shop shop;
//Extra value to go in your join table
public String someValue;
...
}
Then Shop
and Product
each have a one to many relationship with ProductShop
Inserting entries into the table is done manually
ProductShop ps = new ProductShop();
ps.psKey.productId = someProductId;
ps.psKey.shopId = someShopId;
ps.someValue = someValue;
ps.save();
Upvotes: -1
Reputation: 1267
I have Apps
and Users
. Each app can have several Users, each User can use several Apps.
In your case, you can replace App
with Product
and User
with Shop
Here is my working code under Play! 2.2.2
Evolutions of DB :
create table app_user (
id varchar(40) not null,
constraint pk_fb_user primary key (id)
);
create table app (
id varchar(40) not null,
name text,
constraint pk_app_id primary key (id)
);
create table membership (
app_id varchar(40) not null,
app_user_id varchar(40) not null,
constraint fk_membership_app_id foreign key (app_id) references app,
constraint fk_membership_app_user_id foreign key (app_user_id) references app_user
);
Model App
@Entity
public class App extends Model {
@Id
public UUID id;
@Column
public String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "membership")
public List<User> users;
....
}
Model User
@Entity
@Table(name = "app_user")
// user is reserved keyword in DB
public class User extends Model {
@Id
public UUID id;
}
I don't need to access Apps of a User so I didn't have an App field in User.
Upvotes: 5