Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
11. Aug 2008, 11:37 CET | Link

I have a problem with EntityHome objects and custom validation code. The problem is really simple but I don't know how to fix it in a seam manner. When working with EntityHome forms are directly bound to the managed entity instances. If I do a submit the setters of the entity will be invoked and hibernate will update the database automatically since the entity is still managed. My problem is that I need to do some additional validation before updating the database (i. e. checking for invalid value combinations). Usually I would do it in a save/update method before calling persist()/merge(). But in this case, the entity is updated automatically.

How and where can I do these validation checks when using EntityHome objects?

6 Replies:
13. Aug 2008, 10:46 CET | Link

Anybody can help please? I have absolutely no idea how to solve that problem in a seam manner.

13. Aug 2008, 14:40 CET | Link

Change:

@Override @Begin
public void create() {
    super.create();
}

To:


@Override @Begin(flushMode=FlushModeType.MANUAL)
public void create() {
    super.create();
}

That will prevent the automatic flushing. Now, think of how you are going to architect this next. The first reaction might be to override the update and persist methods and remove the entityManager.flush(); method, but remember, it is needed for the persist method to actually set the ID, and the flush is the only effective line in the update method, so you should rearchitect your view or add more buttons.

The other and better option, now that I am reading your original post again, is to forget everything I said above, and just override the persist method like so:

@Transactional
   public String persist()
   {
      //Do your additional validation here before persisting
      getEntityManager().persist( getInstance() );
      getEntityManager().flush();
      assignId( PersistenceProvider.instance().getId( getInstance(), getEntityManager() ) );
      createdMessage();
      raiseAfterTransactionSuccessEvent();
      return "persisted";
   }

Also, have you considered writing your own hibernate validators?

13. Aug 2008, 16:06 CET | Link

Within your custom validator, you could create an instance of import org.jboss.seam.ui.validator.ModelValidator and invoke the model validation. You can put it before or after your own validation and it uses the hibernate annotations on your entity bean (if this is what you are looking for).

14. Aug 2008, 10:26 CET | Link

Nice idea with the custom validator. Unfortunately, I couldn't find good documentation about that topic in a rush. Do you mean implementing the custom validation by using the EntityListeners like described here?

Do you have any good bookmarks regarding that topic?

14. Aug 2008, 10:20 CET | Link

Thank you very much! That was a good idea. Unfortunately, it didn't work for me but you gave me an idea how to solve it.

The problem was caused by invoking the setters of the entity when a form was submitted. With the code snippet above you gave me an idea how to solve it. It is really simple:


public String update() {
    if (!valid()) {
        // rollback the updates caused by the setters
        Transaction.instance.rollback();
    }
    super.update();
}

I hope that this solution do not have any bad side effects. What do you think of this solution?

25. Nov 2008, 17:58 CET | Link

Bit of a bump for this topic as I'm experiencing the same troubles but the suggested fixes aren't working for me. Does anyone else have any other suggestions to get past this problem. Here's my situation:

I've got an page with values bound to my EntityHome. That contains an update method like below:

public String update() {
  boolean errorsFound = false;

  if (StringUtils.isBlank(getInstance().getExternalId())) {
    errorsFound = true;
    getFacesMessages().addToControlFromResourceBundleOrDefault(
        "selectedProjectExternalId", SEVERITY_ERROR,
        "sso.manager.project.blankid",
        "Please enter an external ID for the project.");
  }

  // More checks for errors here

  if (errorsFound) {
    return FAILURE.toString();
  }
  return super.update();
}

If I enter values that fail the validation, the error messages are shown but the database seems to still be updated to match the now incorrect data in the instance. All the conversations in my application are started with FlushMode set to true (via pages.xml) so I'm not 100% why this is happening.