Hi,
my problem occurs on updating an AttributeValue as this
doesn't trigger an index update. :( I have a complicated model in my application. For this reason I am using the IndexEmbedded-Annotation in my Product-Class to keep some attributes for that Product. And in the Attribute.class I am using IndexEmbedded for indexing different AttributeValue's for that Attribute.
Everything works fine in my application if I only insert or delete products. But if I update an AttributeValue the change is made persistent in the database, but the lucene-index isn't updated although I use @ContainedIn to build bidirectional relationships.
So why isn't my index kept up to date in this case? Does anybody have an idea?
Here the concrete code. I have the following classes in my Application with some Annotations:
I have a product with a Collection of Attributes:
Code:
@IdClass(ProductPK.class) @Entity(name = "product") @Table(name = "product")
@Indexed @Analyzer(impl = GermanAnalyzer.class)
public class Product extends AbstractProduct<Product, ProductPK> {
@OneToMany(mappedBy = "product", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.REMOVE })
@IndexedEmbedded
private Collection<Attribute> attributes;
...
the Attribute.class looks like:
Code:
@Entity(name="productAttribute") @Table(name="product_attribute")
@org.hibernate.annotations.Table(indexes={@Index(name="nameIndex", columnNames={"name"})}, appliesTo = "product_attribute")
public class Attribute extends AbstractAttribute<Attribute> {
@ManyToOne
@ContainedIn
private Product product;
@OneToMany(mappedBy="attribute", fetch=FetchType.LAZY, cascade={CascadeType.PERSIST,CascadeType.REMOVE})
@OrderBy("order asc")
@IndexedEmbedded
private List<AttributeValue> values;
...
The AttributeValue.class looks like:
Code:
@Entity(name="attributeValue")
@Table(name="product_attribute_value")
public class AttributeValue extends AbstractAttributeValue<AttributeValue> {
@ManyToOne(targetEntity=Attribute.class, fetch=FetchType.EAGER)
@ContainedIn
private Attribute attribute;
...
And the superclass of AttributeValue: AbstractAttributeValue.class looks like:
Code:
@MappedSuperclass
public abstract class AbstractAttributeValue<T extends AbstractChangeableEntity<T, Integer>>
extends AbstractChangeableEntity<T, Integer> {
@Column(name = "_value")
@Field(index = Index.TOKENIZED, store = Store.YES)
private String value;
...
and last but not least the code which I want to use to update an AttributeValue. perhaps my mistake is already here but I don't see it.
Code:
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("lof");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
String variante = "Variante 123 xyz";
Query q = em
.createQuery("select p from product p where p.variante=:variante");
q.setParameter("variante", variante);
q.setMaxResults(1);
Product p = null;
try {
p = (Product) q.getResultList().get(0);
System.out.println(p.getId());
} catch (NoResultException e) {
System.out.println("No entity found for query");
System.exit(0);
}
Attribute kommentarAttribut = null;
Collection<Attribute> attributes = p.getAttributes();
for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
Attribute attribute = (Attribute) iterator.next();
if (attribute.getName().equals("Kommentar")) {
kommentarAttribut = attribute;
break;
}
}
List<AttributeValue> values = kommentarAttribut.getValues();
for (Iterator iterator = values.iterator(); iterator.hasNext();) {
AttributeValue attributeValue = (AttributeValue) iterator.next();
System.out.println(attributeValue.getValue());
attributeValue
.setValue(new Date()
+ " changing the AttributeValue");
}
em.merge(p);
em.getTransaction().commit();
em.close();