Thank you, i overlooked that. I finally got it fully working with no @Generated annotation, I had to remove the method and @ManyToMany on Product in Order otherwise it went into objectdb internal error. Now everything is persisted automatically everywhere, it merges when expected, it uses provided indexes and there is no more doublons, great!
package testodb;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;
public class TestODB_sameID implements Serializable {
public static void main(String[] args) {
Test t = new Test();
t.test();
}
public static class Test{
EntityManagerFactory emf;
EntityManager em;
void test(){
Category cat1 = new Category(1);
Category cat2 = new Category(2);
Category cat3 = new Category(3);
Customer cust1 = new Customer(1);
Customer cust2 = new Customer(2);
Customer cust3 = new Customer(3);
Product prod1 = new Product(12,cat1);
Product prod2 = new Product(22,cat2);
Product prod3 = new Product(32,cat1);
Order ord1 = new Order(1,cust1,prod1);
Order ord2 = new Order(2,cust2,prod2);
Order ord3 = new Order(3,cust3,prod3);
Order ord4 = new Order(4,cust1,prod3);
Order ord5 = new Order(5,cust2,prod2);
Order ord6 = new Order(6,cust3,prod2);
openDB();
addProduct(prod1);
addProduct(prod2);
addProduct(prod3);
closeDB();
openDB();
addOrder(ord1);
addOrder(ord2);
addOrder(ord3);
closeDB();
openDB();
addOrder(ord4);
addOrder(ord5);
addOrder(ord6);
closeDB();
}
@Entity public static class Product implements Serializable {
@Id
private long id;
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
private List<Category> categories = new ArrayList();
public Product(int id,Category cat) {
this.id = id;
this.categories.add(cat);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@Entity public static class Order implements Serializable {
@Id
private long id;
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
private Customer cust;
//@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
private List<Product> orderRow = new ArrayList();
public Order(long id,Customer cust,Product prod) {
this.id = id;
this.cust = cust;
this.orderRow.add(prod);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@Entity public static class Category implements Serializable {
@Id
private long id;
public Category(int id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
@Entity public static class Customer implements Serializable {
@Id
private long id;
public Customer(int id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
synchronized void addProduct(Product prod){
System.out.println("add product ["+ prod.getId()+"]");
checkActive();
em.persist(prod);
try{em.getTransaction().commit();}
catch( PersistenceException ex){
System.out.println("product ["+ prod.getId()+"] must be merged");
checkActive();
em.merge(prod);
em.getTransaction().commit();
}
}
synchronized void addOrder(Order ord){
System.out.println("add order ["+ ord.getId()+"]");
checkActive();
em.persist(ord);
try{em.getTransaction().commit();}
catch( PersistenceException ex){
System.out.println("order ["+ ord.getId()+"] must be merged");
checkActive();
em.merge(ord);
em.getTransaction().commit();
}
}
synchronized void openDB(){
emf = Persistence.createEntityManagerFactory(
"objectdb:$objectdb/db/testc.tmp"); //;drop
em = emf.createEntityManager();
}
synchronized void closeDB(){
em.close();
emf.close();
}
void checkActive(){
if(!em.getTransaction().isActive()) em.getTransaction().begin();
}
}
}