2010-03-16 5 views
0

У меня есть некоторые проблемы с пониманием поведения JPA. Маби кто-нибудь мог дать мне подсказку. Ситуация:JPA поведение

сущность продукта:

@Entity 
public class Product implements Serializable { 
... 
@OneToMany(mappedBy="product", fetch=FetchType.EAGER) 
private List<ProductResource> productResources = new ArrayList<ProductResource>(); 
.... 
public List<ProductResource> getProductResources() { 
    return productResources; 
} 
public boolean equals(Object obj) { 
    if (obj == this) return true; 
    if (obj == null) return false; 
    if (!(obj instanceof Product)) return false; 
    Product p = (Product) obj; 
    return p.productId == productId; 
} 
} 

объект ресурса:

@Entity 
public class Resource implements Serializable { 
... 
@OneToMany(mappedBy="resource", fetch=FetchType.EAGER) 
private List<ProductResource> productResources = new ArrayList<ProductResource>(); 
... 
public void setProductResource(List<ProductResource> productResource) { 
    this.productResources = productResource; 
} 
public List<ProductResource> getProductResources() { 
    return productResources; 
} 
public boolean equals(Object obj) { 
    if (obj == this) return true; 
    if (obj == null) return false; 
    if (!(obj instanceof Resource)) return false; 
    Resource r = (Resource) obj; 
    return (long)resourceId==(long)r.resourceId; 
} 
} 

ProductResource Entity: Это JoinTable (ассоциация класса) с дополнительными свойствами (сумма). Он отображает продукт и ресурсы.

@Entity 
public class ProductResource implements Serializable { 
... 
@JoinColumn(nullable=false, updatable=false) 
@ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST) 
private Product product; 

@JoinColumn(nullable=false, updatable=false) 
@ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST) 
private Resource resource; 

private int amount; 

public void setProduct(Product product) { 
    this.product = product; 
    if(!product.getProductResources().contains((this))){ 
     product.getProductResources().add(this); 
    } 
} 
public Product getProduct() { 
    return product; 
} 
public void setResource(Resource resource) { 
    this.resource = resource; 
    if(!resource.getProductResources().contains((this))){ 
     resource.getProductResources().add(this); 
    }  
} 
public Resource getResource() { 
    return resource; 
} 
... 
public boolean equals(Object obj) { 
    if (obj == this) return true; 
    if (obj == null) return false; 
    if (!(obj instanceof ProductResource)) return false; 
    ProductResource pr = (ProductResource) obj; 
    return (long)pr.productResourceId == (long)productResourceId; 
} 
} 

Это сеанс Bean (работает на стеклянной рыбке).

@Stateless(mappedName="PersistenceManager") 
public class PersistenceManagerBean implements PersistenceManager { 

@PersistenceContext(unitName = "local_mysql") 
    private EntityManager em; 

public Object create(Object entity) { 
    em.persist(entity); 
    return entity; 
} 
public void delete(Object entity) { 
    em.remove(em.merge(entity)); 
} 
public Object retrieve(Class entityClass, Long id) { 
    Object entity = em.find(entityClass, id); 
    return entity; 
} 
public void update(Object entity) { 
    em.merge(entity); 
} 
} 

Я называю сеанс Bean от клиента Java:

public class Start { 
public static void main(String[] args) throws NamingException { 

    PersistenceManager pm = (PersistenceManager) new InitialContext().lookup("java:global/BackITServer/PersistenceManagerBean"); 

    ProductResource pr = new ProductResource(); 
    Product p = new Product(); 
    Resource r = new Resource(); 

    pr.setProduct(p); 
    pr.setResource(r); 

    ProductResource pr_stored = (ProductResource) pm.create(pr); 

    pm.delete(pr_stored); 
    Product p_ret = (Product) pm.retrieve(Product.class, pr_stored.getProduct().getProductId()); 
// prints out true ???????????????????????????????????? 
    System.out.println(p_ret.getProductResources().contains(pr_stored)); 
} 
} 

Так вот идет моя проблема. Почему объект ProductResource все еще находится в списке ProductResources (см. Код выше). Коррекция productResource в db исчезает после удаления, и я снова извлекаю объект Product. Если я правильно понял, каждый вызов метода клиента происходит в новом контексте персистентности, но здесь я, очевидно, возвращаю не обновленный объект продукта !?

Любая помощь приветствуется

Благодаря

Marcel

+0

Можете ли вы показать запросы SQL, которые выполняются на стороне сервера? –

ответ

0

Когда я использую метод обновления в методе извлечения он работает.

public Object retrieve(Class entityClass, Long id) { 
    Object entity = em.find(entityClass, id); 
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    em.refresh(entity); 
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    return entity; 
} 

Так что я предполагаю, что проблема заключается в кешировании затмения. Если я использую метод create в объекте ProductResource, объекты Product и Resource также сохраняются (cascade = CascadeType.Persist). Когда я загружаю объект Product снова, он выходит из кеша и поэтому не является актуальным. Поэтому я должен просто удалить объект ProductResource в списках объекта Product и Resource и выполнить обновление. Правильно? Вызов refresh() в этом месте действительно не имеет смысла, поскольку он обходит кеширование.

Благодаря Marcel

Смежные вопросы