JPA returning null for deleted items from a set

Posted by Jon on Stack Overflow See other posts from Stack Overflow or by Jon
Published on 2010-05-02T07:38:08Z Indexed on 2010/05/02 7:47 UTC
Read the original article Hit count: 200

Filed under:
|
|
|

This may be related to my question from a few days ago, but I'm not even sure how to explain this part. (It's an entirely different parent-child relationship.)

In my interface, I have a set of attributes (Attribute) and valid values (ValidValue) for each one in a one-to-many relationship. In the Spring MVC frontend, I have a page for an administrator to edit these values. Once it's submitted, if any of these fields (as <input> tags) are blank, I remove the ValidValue object like so:

Set<ValidValue> existingValues = new HashSet<ValidValue>(attribute.getValidValues());
Set<ValidValue> finalValues = new HashSet<ValidValue>();
for(ValidValue validValue : attribute.getValidValues()) {
    if(!validValue.getValue().isEmpty()) {
        finalValues.add(validValue);
    }
}

existingValues.removeAll(finalValues);
for(ValidValue removedValue : existingValues) {
    getApplicationDataService().removeValidValue(removedValue);
}
attribute.setValidValues(finalValues);
getApplicationDataService().modifyAttribute(attribute);

The problem is that while the database is updated appropriately, the next time I query for the Attribute objects, they're returned with an extra entry in their ValidValue set -- a null, and thus, the next time I iterate through the values to display, it shows an extra blank value in the middle. I've confirmed that this happens at the point of a merge or find, at the point of "Execute query ReadObjectQuery(entity.Attribute).

Here's the code I'm using to modify the database (in the ApplicationDataService):

public void modifyAttribute(Attribute attribute) {
    getJpaTemplate().merge(attribute);
}

public void removeValidValue(ValidValue removedValue) {
    ValidValue merged = getJpaTemplate().merge(removedValue);
    getJpaTemplate().remove(merged);
}

Here are the relevant parts of the entity classes:

Entity
@Table(name = "attribute")
public class Attribute {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "attribute")
    private Set<ValidValue> validValues = new HashSet<ValidValue>(0);
}

@Entity
@Table(name = "valid_value")
public class ValidValue {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "attr_id", nullable = false)
    private Attribute attribute;
}

© Stack Overflow or respective owner

Related posts about jpa

Related posts about orm