-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Enforcing non-duplicate sibling names in trees
PostPosted: Fri May 11, 2007 5:30 pm 
Newbie

Joined: Fri May 11, 2007 4:47 pm
Posts: 3
I am using Hibernate 3.0 with annotations


My problem is that I am trying to create a simple tree structure for a basic CRM system and I wish to enforce the rule that no two siblings may have the same name.

I have a base-class Content and e.g. two subclasses Page and Folder using the one-table per class-hierarchy model (i.e. with a Discriminator column).

Every Content object has a parent property and a String name property.

It is illegal to have two objects with the same parent and the same name.

There seem to be two solutions to my problem:

1) Implement an Interceptor which checks for the pre-existence of another Content object with the same name and parent as the entity being persisted or updated.

2) Implement @PrePersist et al methods on the entities themselves.

If I use 1) I am binding my implementation to Hibernate and, in the general case (i.e. if I wish to enforce more complicated rules for other properties) I will need a switch statement on the class of the entity to choose the correct DAO to which the checks should be forwarded. Thus every time I add a new Content subclass to the system I need to modify the Interceptor to be aware of the subclass.

If I use 2) then I am forced either to allow Hibernate to load all siblings so that I can iterate over them to determine if one already has the name I wish to assign, or the entity must have access to the relevant DAO in order that it can determine the existence of a same-named sibling through a simple query rather than having to load the entire child set into memory. Viz:

Code:
/**
* I don't like this because if there are many children it is very wasteful of
* memory and CPU intensive
**/
@PrePersist
public void onPrePersist() throws Exception {

  Folder p = this.getParent();
  /**
  * This is the root folder so it has no parent
  **/
  if(p == null) {
    return;
  }

  for(Content c : p.getChildren()) {
    if(c.getName().equals(this.getName())) {
      throw new Exception("Synonyms are not allowed);
    }
}


/**
* This is preferable for efficiency
**/
@PrePersist
public void onPrePersistUsingDAO() throws Exception {
  ContentDAO dao = ContentDAOFactory.getDaoFor(this);
  Content sibling = dao.getContentByNameAndParentId(this.getName(), this.getParent().getId()); // BTW. How can I get access to the parent_id property??
  if(content != null) {
    throw new Exception("Synonyms not allowed");
  }
}

Sidenote: I use the onPrePersist method and annotations and call it from my Interceptor so that the code will carry on working if deployed within an EJB3 or JPA EntityManager.

So what I wish to know is:

a) Is there a recommended way of doing this sort of thing e.g. using some sort of collection for a Folder's children which is keyed on name and which Hibernate understands so that I can rewrite the above method as:

Code:
@PrePersist
public void onPrePersist() throws Exception {
  Content sibling = this.getParent().getChildren().findByKeyValue("name",this.getName());
  if(sibling != null) {
    throw new Exception("Synonyms not allowed");
  }
}

With the hope that Hibernate will turn the findByKeyValue() call into a query.

or

b) Is there some way of asking the PersistenceManager to redirect all persist and update calls through a DAO so that the entity itself does not need to know what is going on? (If you say 'that is what the Interceptor is for' I will understand)

Finally, my preference is for the onPrePersistUsingDAO() approach since it encapsulates entity class specific code where I believe it belongs. I do understand that this breaks the "POJOs are dumb and don't know they are persistent" philosophy. Do I get a slap on the wrist for even thinking this? Or is it acceptable to admit that persistent entities should know that they are persistent and have a storage mechanism?

I have to admit that to me the POJO+DAO model seems to be a thinly disguised struct+function call. It breaks inheritance and polymorphism and requires code using the entities to do a lot of type-checking to determine which DAO to use.

I hope I am just being, um, let's say - unimaginative? - about this!

Thanks for any help and advice you can give me.

Duncan
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.