Ulf
Ulf

Reputation: 43

Update only changed entity fields and check for changes by other users in EJB

In an EJB-class i have two methods with remote interface:

Class MyBean {
    public CustomerEntity getCustomer(String id) {......}
    public void updateCustomer(CustomerEntity newValues, CustomerEntity oldValues) {......}
}

Customer Entity consist of some fields with getters and setters.

@Entity 
public class Customer {
    @ID private String id;
    @Column private String name;
    @Column private String phone;
    // Getters and setters 
    .
    .
}

The client app does:

Customer customer myBeanRemoteInterface.getCustomer("some id");
Customer oldCustomer = customer;    //Save original customer data
displayCustomerFormAndAcceptChanges(customer);
myBeanRemoteInterface.updateCustomer(customer, oldCustomer);

The EJB updateCustomer should now update the customer on the server. To avoid write over any changes made to other fields by other users, only fields that the user has changed should be commited. Like the following:

public void updateCustomer(CustomerEntity newValues, CustomerEntity oldValues) {
    Customer customer = entityManager.find(Customer.class, oldValues.getId());
    if (!newValues.getName().equals(oldValues.getName()) { // Value updated
        // If the value fetched by entityManager.find is different from what was originally fetched that indicates that the value has been updated by another user.
        if (!customer.getName().equals(oldValues.getName()) throw new CustomerUpdatedByOtherUserException();
        else customer.setName(newValues.getName());
    }
    // repeat the code block for every field in Customer class
    entityManager.flush();
}

The problem now is that the code block in updateCustomer needs to be repeated once for every field in the Customer class. If new fields is inserted into the Customer class, also the EJB needs to be updated.

I need a solution that works without any need for updateing the EJB if more fields is added to Customer class.

Any suggestions?

Upvotes: 1

Views: 1561

Answers (2)

Ravi Trivedi
Ravi Trivedi

Reputation: 2360

Use Java Reflection:

     Method[] methods = Customer.class.getDeclaredMethods();
     Class<?>[] methodParams = null;
     Object[] paramValue = new Object[1];

     for (Method method : methods) {

       if(method.getName().contains("set")) //This is for set methods. 
       {
           methodParams = method.getParameterTypes();
           if(methodParams[0].equals(String.class))
           {
               paramValue[0] = "some string"; // Assigning some value to method parameter
           }

           method.invoke(customer, paramValues); // customer is your object you are executing your methods on.
       }
    }

Upvotes: 1

bigZee77
bigZee77

Reputation: 340

You should really consider adding a @Version annotated field to your Entity to have your JPA implementation take care of Optimistic Locking and then deal with situations where you try to update using "stale" data. Otherwise you're jeopardizing your data-integrity.

Cheers //Lutz

Upvotes: 0

Related Questions