Using Annotations to add Validity Constraints to JavaBeans?

Discussions

News: Using Annotations to add Validity Constraints to JavaBeans?

  1. When building domain models in Java, contraints to fields in a class are typically defined and enforced in the code, usually in setter methods. While us OO developers love to see this type of data validation logic expressed in code, Anders Holmgren argues that it can lead to duplication of validation code across tiers, or even worse, developers purposefully not validating in certain places where they should be, in order to avoid such duplication.

    One solution would be to declaratively define constraints that could then be re-used throughout your application, similar to how Web Services standards use XML Schema to define constraints on data that is exchanged.

    In a new article on java.sun.com, Anders Holmgren proposes the use of annotations to add validity constraints to objects, declaratively, like this:
    public class Address {
        @MaxLength(20)
        public String street;

        ....
    }
    Anders also suggests standardizing them so that we could realize a number of benefits such as:

    • Allowing introspection of constraints
    • When used with a good validation framework it would result in little, if any, application code would be required for enforcement.
    • Constraints could theoretically be defined in your classes once, and then automatically applied (re-used in other tiers).
    • It would allow the implementation of sophisticated validation frameworks that could even be integrated into existing validation frameworks.
    • Existing IDE support for annotations would make contraint annotations easy to work with.
    Anders implemented some annotations and also provided an example validation framework. While Anders acknowledges some limitations to the approach, he believes it to be a pragmatic and useful solution to an important problem.

    What do you think?

    Threaded Messages (94)

  2. In *real word* applications validations done using data in database. So IMHO this is very limited.
  3. In *real word* applications validations done using data in database. So IMHO this is very limited.

    Wow, what a pile of nonsense in a couple of words.
  4. In *real word* applications validations done using data in database. So IMHO this is very limited.
    Wow, what a pile of nonsense in a couple of words.

    May I ask why is it "pile of nonsense" (Yea, I misspelled *world*)
  5. In *real word* applications validations done using data in database. So IMHO this is very limited.
    Wow, what a pile of nonsense in a couple of words.
    May I ask why is it "pile of nonsense" (Yea, I misspelled *world*)

    I am not the author of the first reponse, but I dare to guess a few reasons: First, the example in the original article validates before going to the database. This can give better responsivity, better error messages, and better error handling. Plus the domain objects will be validated before you execute other business logic with them! Second, if you want this kind of validation in the database, you start treading into the territory of stored procedures and triggers, I am not sure that's such a nice place to be. Third, most *real world* java applications also validate in the domain objects. If you don't, you probably don't want to use domain objects in the first place, as they would at best be anemic, at worst error prone (if they have logic that must work despite validation errors). Anemic domain models (aka DTOs) is IMHO the worst anti-pattern in the history of Java.

    If you don't have domain object, this approach (and possibly J2EE) is not a good match for you. If you have domain objects, you'd want to validate in them, not (only) in the database.
  6. Anemic domain models (aka DTOs) is IMHO the worst anti-pattern in the history of Java.

    First off DTOs preceede Java. Secondly why would you call them domain models, even if anemic?

    That aside, care to explain why are they such a menace?
  7. Anemic domain models (aka DTOs) is IMHO the worst anti-pattern in the history of Java.
    First off DTOs preceede Java. Secondly why would you call them domain models, even if anemic?That aside, care to explain why are they such a menace?

    DTO is a transport pattern that keeps behavior out and focusses on the data. IMHO it might as well be called DTS (Data Transport Struct). If all you have representing your domain is DTOs then you're maybe not using OO as well as it could be used. Instead you're probably using the Transaction Script pattern. Martin Folwer has things to say about this, and Domain Driven Design, by Eric Evans is a good read too.

    My experience is that folks don't feel Transaction Script is a menace (in that *real world* place that keeps coming up). My experience is also that applications get pretty darn complex and that Transaction Script only goes so far. When I've had a rich domain model it's made life easier. Not only did it keep domain data and behavior better contained and expresive, it also helped me to make better facades, which in turn lead to clearer transport boundaries (where the DTOs came in).

    I've also found it very hard to get the idea of rich domain models accepted as a core approach in projects I've been on. I'm not sure why. Maybe I'm to feisty. But it feels more like I'm run over by inertia and that patterns in J2EE and SOA seem to lead folks away from rich domains. Again, I don't know why, but I think it's because those things are mostly about transport because they are about distributed applications.

    $0.02
    ,boz
  8. Chris, I know what DTO is and what it's good for. You said they're the worst anti-pattern ever, for Java at least. I didn't think that's a reasonable thing to say, that's all.
    The DTOs live at system borders - borders with the database, remote systems, GUIs and whatnot. What's inside these borders - it can very well be a procedural or domain driven design, I don't think that has any relevance on the use of DTO. What I'm saying is that maybe you wanted to warn against some problems but picked the wrong fight.
  9. Constraints in the database[ Go to top ]

    Chris, I know what DTO is and what it's good for. You said they're the worst anti-pattern ever, for Java at least. I didn't think that's a reasonable thing to say, that's all.The DTOs live at system borders - borders with the database, remote systems, GUIs and whatnot.
    Pretty much what he is saying is wrong with them. They are not needed anywhere except maybe remoting - but I've not needed them there either. If you need "separation" between the "layers" use interfaces..
  10. Constraints in the database[ Go to top ]

    Mark, DTOs are structs. How can they not be needed ? Of course they're needed at system boundaries, it's simply not feasable to getXXX() 10 times to obtain all Address components when that can lead to cache checks, remote invocation and whatnot, when you really just need like 384 bytes of data.
  11. Constraints in the database[ Go to top ]

    Mark, DTOs are structs. How can they not be needed ? Of course they're needed at system boundaries, it's simply not feasable to getXXX() 10 times to obtain all Address components when that can lead to cache checks, remote invocation and whatnot, when you really just need like 384 bytes of data.

    I understand that issue.

    But what is the difference between, for instance, Person(a domain object) and PersonDTO?
  12. Constraints in the database[ Go to top ]

    Also Mark cheap advice on interfaces is just so September already! Live up to the hype. Layers have since become services, or service-oriented. I'm not sure why you're quoting separation as "separation" - you don't really mean it, is separation actually "separation" i.e. it's just all in our heads? Also those were not layers (or is it "layers"?) but systems. And you're not sending your database interfaces are you?
    And Chris never actually said DTOs are bad per se but lack of a strong (as opposed to anemic or weak) domain model is, although even that might work in the "real world" - quotes again, "hello" is "this the" Matrix ?
  13. Constraints in the database[ Go to top ]

    Also Mark cheap advice on interfaces is just so September already!
    Yes, it was for free.
     Live up to the hype. Layers have since become services, or service-oriented. I'm not sure why you're quoting separation as "separation" - you don't really mean it, is separation actually "separation" i.e. it's just all in our heads?
    I'm going to have to guess what you meant. Yes, some of it is in peoples heads. The Entity EJB issue is not.
    Also those were not layers (or is it "layers"?) but systems. And you're not sending your database interfaces are you?
    I'm not "sending" my database anything. And yes, I am using interfaces.
  14. Constraints in the database[ Go to top ]

    OK, this is getting tiresome. You may live in an EJB world and have EJB issues - I don't. DTOs are not something that came about with EJB. As most pattern guides will also tell these are just simple data structures, objects by value, used at system boundaries. You cannot expose your Customer's information by presenting an interface as that will lead to several round-trips in order to fetch first, last names etc. You also do not exchange interfaces with other systems that you interact with: for instance, the database.
  15. Constraints in the database[ Go to top ]

    OK, this is getting tiresome. You may live in an EJB world and have EJB issues - I don't. DTOs are not something that came about with EJB. As most pattern guides will also tell these are just simple data structures, objects by value, used at system boundaries. You cannot expose your Customer's information by presenting an interface as that will lead to several round-trips in order to fetch first, last names etc. You also do not exchange interfaces with other systems that you interact with: for instance, the database.
    I don't live in an ejb world. But I do live in a distributed world. And I don't need simple data structures. I don't have round tripping issues. The database is not a system in my world. It is a technology and is used as part of my system.

    What you are describing as a problem IS the problem many have with Entity EJBS.

    Why do you need structs vs full-fledged domain objects? If a remote method returns a DTO, can it not return a domain object?

    I'm not trying to be jerk. Please take a look at the link I provided. I've had to go into too many systems and remove all the unnecessary struct/dto/array code - or at least push it to the boundaries.
    Also, check out Martin Fowlers Architecture book on how to deal with dto's/structs when you do have to use them.
  16. Constraints in the database[ Go to top ]

    Why do you need structs vs full-fledged domain objects? If a remote method returns a DTO, can it not return a domain object?

    Real-world example: suppose your domain object is persisted through ORM, or some objects have permanent connections to resources. I had this problem last year when we made intensive use of Hibernate Objects with lazy instantiations of attributes and associations. The mapped objects, if transfered to the web layer, could trigger an unwanted DB query if a "lazy" property was accessed. The master architect chose to use DTO to bypass this problem, limiting mapped objects to EJB internal use. Of course we had to write a lot of code that just copied data from Domain Objects to DTO and vice versa.

    And yes, I know that the object can be detached from the Hib Session. This is exactly the solution I imagine for this year's work. Still, a not-so-skilled programmer could make some embarassing mistakes if the Domain Objects are too "smart".
  17. Constraints in the database[ Go to top ]

    Hmmm. Sounds like DTOs are the least of your worries. :(

    Thanks for sharing your experience. A possible way to remove the attribute copying is to use delegation. A good IDE will generate the delegation methods. If the DTO/struct/array is trully just that (no logic at all), it'll work and save you some effort.

    Personally, I would have solved it a different way, but since you've got to deal with it, try the above suggestion.
  18. Constraints in the database[ Go to top ]

    A possible way to remove the attribute copying is to use delegation. A good IDE will generate the delegation methods. If the DTO/struct/array is trully just that (no logic at all), it'll work and save you some effort.

    Agreed. Indeed, it is what I would have done to pass data from the DTO to the Struts FormBean, which was another, almost equal object. Incidentally, the FormBean added only validation logic to the DTO. However, we managed to copy data in that case, too (and yes, we managed to copy the data from object to object twice - don't ask me why, it was not my decision).

    However, delegation is not a solution for the still-mapped object problem. If the invocation of an accessor method can trigger an undesirable side effect due to the internal "logic" of the domain object, the delegator is as dangerous as the object because it invokes the accessor.
    I do the same thing you do, only I return a domain object.

    Whatever that means. It either has struct semantics or not.

    Hmm, this discussion is becoming interesting, although a bit off-topic. I am currently designing a new system and want to get rid of past errors. Let me summarize the terms, as I understand them:

    A Domain Object is an object that does not follow any special requirement but being the Java representation of a Entity that has been modeled at requirement analysis time. It could (and should) contain some business logic, at least data validation. A Domain Object may be persisted via ORM. A Domain object might be not serializable.

    A DTO is the serializable copy of a Domain Object (JavaBean or C / CORBA struct). It has no logic inside, and all of its properties are settable by external object via accessors. It is always serializable.

    A "Service Implementor" (my terminology) is an object that conforms to some framework's constraints (EJB, Spring, etc.) and as such might not be inserted in a simple hierarchy of Java Objects. The framework manages persistence, remoteness and resource management.

    If I understand it, the trouble with Domain Objects is that at layer border they could be passed to a remote client only by reference (EJB or CORBA interface-like). And this means statefulness and subsequent calls of remote accessors (a questionable practice in J2EE).

    Did I get the point?
  19. With the exception of "and all of its properties are settable by external object via accessors." yes, you did get the point.
    It's a chunk of data. Accessor as seen in the 2nd account_info (the interface, which may very well be a proper domain object) are evil, they call back to the server.
  20. Constraints in the database[ Go to top ]

    A Domain Object is an object that does not follow any special requirement but being the Java representation of a Entity that has been modeled at requirement analysis time.
    If this is true then there is no need for this -
    A DTO is the serializable copy of a Domain Object (JavaBean or C / CORBA struct).

    Just make the Domain object serializable. No need to make a copy.

    If you use Hibernate, use ver 3.0 and the new Eclipse tools to generate domain objects from the database structure. See what interface they implement.
  21. Constraints in the database[ Go to top ]

    A Domain Object is an object that does not follow any special requirement but being the Java representation of a Entity that has been modeled at requirement analysis time.
    If this is true then there is no need for this -
    A DTO is the serializable copy of a Domain Object (JavaBean or C / CORBA struct).
    Just make the Domain object serializable. No need to make a copy.If you use Hibernate, use ver 3.0 and the new Eclipse tools to generate domain objects from the database structure. See what interface they implement.

    Oh yeah, and check out AOP to help separate out the persistance, communiction and transportation concerns.
  22. Constraints in the database[ Go to top ]

    A Domain Object is an object that does not follow any special requirement but being the Java representation of a Entity that has been modeled at requirement analysis time.
    If this is true then there is no need for this -
    A DTO is the serializable copy of a Domain Object (JavaBean or C / CORBA struct).
    Just make the Domain object serializable. No need to make a copy.If you use Hibernate, use ver 3.0 and the new Eclipse tools to generate domain objects from the database structure. See what interface they implement.

    I took an opposite approach with DTO's and Domain objects-- because we support multiple applications within the company I work at, we created DTO's that map 1:1 with our tables. We then have Domain objects that delegate state to DTO's.

    I really don't like the term Domain objects since they are moreover driven by Application requirements, not general business requirements. Example: OrderSession has an OrderDTO, but the OrderSession coordinates behavior such as validation and updating based on the requirements of the application flow, not some general domain specifications. Business rules are best outlined in stateless procedures that act upon behaviorless DTO's-- to some this may seem an odd approach, but it greatly increases reusability as your 'Domain' objects now just coordinate DTO state with stateless business procedures according the application requirements.

    http://hookom.blogspot.com/2004/12/corporate-developer.html
  23. Constraints in the database[ Go to top ]

    Business rules are best outlined in stateless procedures that act upon behaviorless DTO's-- to some this may seem an odd approach, but it greatly increases reusability as your 'Domain' objects now just coordinate DTO state with stateless business procedures according the application requirements.
    This stuff is known as "course grained model", so it is "object oriented" too and there is nothing odd to express entities as structs and procedures in data driven or distributed application. "Domain object" or "Entity" is just a concept and there are many right ways to implement concept. I prefer "course grained model" if application is not a kind of graphical editor too.
  24. Constraints in the database[ Go to top ]

    I took an opposite approach with DTO's and Domain objects-- because we support multiple applications within the company I work at, we created DTO's that map 1:1 with our tables. We then have Domain objects that delegate state to DTO's.I really don't like the term Domain objects since they are moreover driven by Application requirements, not general business requirements. Example: OrderSession has an OrderDTO, but the OrderSession coordinates behavior such as validation and updating based on the requirements of the application flow, not some general domain specifications.

    Hmm, I did something similar myself in 2000 working as a OO designer for IBM. This because we were forbidden to use EJB, which was not that bad considering we had to work with WAS 3.5 (i.e. EJB 1.0 !!! ). When the data was sent to the Presentation Layer, only the DTO passed through, the Domain Object stayed in the business layer.

    However, I am now convinced that this design was a partial mistake on my part. Maybe the lack of OSS technology at that time left me no other choice, but in recent times I noticed that the J2EE gurus tend to dislike all this overusage of DTOs. At that time they were called VOs, and I suspect they were renamed because people started to use theme everywhere instead of where they are needed - at layer interface.
    Business rules are best outlined in stateless procedures that act upon behaviorless DTO's-- to some this may seem an odd approach, but it greatly increases reusability as your 'Domain' objects now just coordinate DTO state with stateless business procedures according the application requirements.

    Again, I have designed like this myself, in the past. But this looks a lot like the anemic model schema, which Fowler considers an antipattern. I am not so convinced that this is the right solution, though you DO need DTOs at some point in an application.
  25. Constraints in the database[ Go to top ]

    Paolo, Mark, etc,

    The approach I'm taking is to use DTOs with Hibernate, and when, for example, I wish to start working with an order, I do:

    OrderHeader hdr = hdrDao.find(id);
    OrderSession session = new OrderSession(hdr);

    session.getExtendedTotal();
    session.validate();

    hdrDao.store(session.getHeader());

    OrderSession follows Sun's Core J2EE patterns' Business Object where state is delegated/encapsulated so the application operates on a Domain. OrderSession itself doesn't have any state other than state that supports the application flow, such as caching.

    You possibly hinted that this approach didn't work for you-- can you please elaborate? I've read Fowler's books/site and actually found Domain models to be be a pain to work with since we ended up duplicating a lot of persistence logic instead of delegating it to a DTO that can be used by any Business Object.

    The other reason is that to use these persistence frameworks, such as Hibernate, you basically need to provide a getter/setter for every field which, to me, seems more anemic than encapsulating/delegating to a purely stateful DTO.

    Any comments would be greatly apprechiated, cheers!
  26. Constraints in the database[ Go to top ]

    Jacob,
     I'm not sure we are refering to the same thing when we say DTO. A DTO is nothing more than private fields and accessors. Anything more, it isn't a DTO (or VO). Is that what you mean as a DTO?

     You don't need to provide accessors with Hibernate. I don't think you do with JDO either. Steve Z?

     I've not fully investigated Sun's patterns, but some of the patterns I have seen (not just from Sun) are not very OO and are not really that good to implement and are really an attempt to solve bad technologies or bad uses of them.
  27. Constraints in the database[ Go to top ]

    Mark, thanks for your comments...

    The DTO's I have are 1:1 mappings with the table columns (w/ UserTypes for things such as Money Objects). They have private vars and getters/setters.

    http://www.corej2eepatterns.com/Patterns2ndEd/BusinessObject.htm

    OrderDTO dto = session.get(OrderDTO.class, id);
    OrderSession order = new OrderSession(dto);
    order.getTotal();

    // auto generate select properties
    // i want to expose to other code participating
    // in ordering
    public OrderSession implements Serializable {
    protected final OrderDTO data;
    public OrderSession(OrderDTO data) {
       this.data = data;
    }
    public Money getTotal() {
      return this.data.getTotal();
    }
    public boolean isValid() {
      // buisiness rules operate on data
    }
    public OrderDTO getData() {
       return this.data;
    }
    }
  28. Constraints in the database[ Go to top ]

    I've actually scrapped the accessors altogether, it's such a built-up concept if the object is really POD.

    Regarding Sun's "patterns" (quotes intended) whenever I remember Fast Lane Reader someone has to pick me up off the floor, throw buckets of water etc. Cheesus !
  29. I've actually scrapped the accessors altogether, it's such a built-up concept if the object is really POD.Regarding Sun's "patterns" (quotes intended) whenever I remember Fast Lane Reader someone has to pick me up off the floor, throw buckets of water etc. Cheesus !

    Lets say that you need to capture and work with some state from the database. At the same time, you only want to expose very little to other code in the application-- encapsulation.

    Are you saying that you wouldn't encapsulate/delegate to a separate object that's representative of the database's state?
  30. That's not the point I was trying to make.
    PODs (POJOs, though not as correct) are just that, structs. I cannot pretend to hide anything from anyone when it comes to say a Customer's names. What I can do on the other hand is have a CustomerManager or CustomerService that can offer services related to the Customer to other layers and/or clients [of the service]. It would for instance erase email and password information when returning a list of Customers as a search result for a query performed by an user (i.e. real person), or build a custom data structure based on several PODs and so on.
    So to answer your question - no, the PODs/DTOs/VOs do not need accessors, they don't do validation nor apply business rules and the like. They're exactly like C structs - and without function pointers.
    At the same time domain concerns (i.e. partitioning the domain into problems that need solving, much like services we have to offer to other parties - including ourselves) take care of all the business needs and that also provides encapsulation both as a goal (i.e. imposed by business rules) and as a side-effect (clearly defined interface for interacting with that domain "parcel").
  31. Constraints in the database[ Go to top ]

    I've actually scrapped the accessors altogether, it's such a built-up concept if the object is really POD.Regarding Sun's "patterns" (quotes intended) whenever I remember Fast Lane Reader someone has to pick me up off the floor, throw buckets of water etc. Cheesus !
    Lets say that you need to capture and work with some state from the database. At the same time, you only want to expose very little to other code in the application-- encapsulation.Are you saying that you wouldn't encapsulate/delegate to a separate object that's representative of the database's state?

    Not writing accessors is one approach. Hibernate allows it easily. I prefer to have the IDE write them automatically, though.

    Jacob: wait a minute (Browsing Crupi's Pattern Catalog). Okay, the book actually says that DTOs are about data encapsulation. I would rather say data packaging. Real encapsulation is another story, which is possible only with a non-anemic model.

    Whenever the responsibility for managing the object state, such as enforcing data constraints [brief attempt to return on-topic], you are breaking the encapsulation rules, not enforcing them. An encapsulated object is responsible for managing its internal state, not only for storing it.

    You can package data even with C or CORBA structs. Does C allow encapsulation IYO ?

    A domain object is really encapsulated, because it contains the entity behaviour, too.

    I have used the approach you suggested, sure. For each entity (table) you usually end up with: OrderDTO, OrderEJB (EntityBean), OrderDTOAssembler, OrderManager (SessionBean), OrderBusinessDelegate, OrderHelper (just to externalize more behavior).

    In the RL example i gave before we also had OrderConverters (Domain-to-DTO and DTO-to-Struts). Anyone interested in knowing the number of developed / auto-generated classes when we were at approx. 20% of the project with a mere four developers? Hundreds.

    People, is this what you would call maintainable code?
  32. Constraints in the database[ Go to top ]

    People, is this what you would call maintainable code?
    Not no, but heck no. Even a Struts app by itself has enough classes. I can only imagine.
  33. Files, files[ Go to top ]

    People, is this what you would call maintainable code?
    Not no, but heck no. Even a Struts app by itself has enough classes. I can only imagine.
    Precisely why I never attempted to use Struts. Too many fucking classes and files and shit for what? A shitty web front-end? No fucking way mate.
  34. Files, files[ Go to top ]

    A shitty web front-end?
    Isn't that redundant? I looked up
    A shitty front-end?
    in the dictionary and it said a web UI
  35. Model, View, Controller
    Smalltalk got it right. Why can't Java?
    Was Oak really that busted that Sun's engineers had not the design room to ensure the fundemental MVC architecture of Smalltalk was built into Java?

    The virtual machine design is based on Smalltalk. Why are we having to add MVC as design-pattern to our apps? Why the large extra namespace of Struts for a basic, fundemental archtectural underpinning that all OO applications require?
     
    Smalltalk was invented in 1971 at Xerox Parc, Goldberg et al
    It's been 34 years. We have mail, telephony, 2D, 3D, multi-media libs, all part of Java, in the Standard edition, but we lack a transparent, well designed, low namespace MVC solution.

    Stewardship means leadership too....
    Matthew
  36. Constraints in the database[ Go to top ]

    For each entity (table) you usually end up with: OrderDTO, OrderEJB (EntityBean), OrderDTOAssembler, OrderManager (SessionBean), OrderBusinessDelegate, OrderHelper (just to externalize more behavior).In the RL example i gave before we also had OrderConverters (Domain-to-DTO and DTO-to-Struts). Anyone interested in knowing the number of developed / auto-generated classes when we were at approx. 20% of the project with a mere four developers? Hundreds.People, is this what you would call maintainable code?

    Within the app I'm writing, I just have OrderDTO and OrderSession. The point of doing so is that other code can capture and work with the raw state of the DB (OrderDTO) without instantiating or having to work with the overhead included with OrderSession-- its constraints, events, etc.

    Now the DTO's I created are considered anemic, but also provide derived state, behavior that is intrinsic ONLY to the specific DTO-- meaining, a ProductDTO has a derived property 'isStocked' where it checks the state that is available to it and returns a boolean without needing to access any extrinsic knowledge.

    I've used the domain pattern on our last application, but consequently, ended up with a bunch of specialized OrderAssembler, OrderManager, OrderService, OrderDelegate-- now multiply that by each behavioral variation in the domain model for Objects that basically work off of the same data (PurchaseOrders, PurchaseLists, VendorQuotes, ConfirmedOrders, etc). Each variation has its own behavior and must be exposed/instantiated through its own set of supporting services/managers/assemblers. Granted there was some abstraction used, but the point is that I ended up with tons of objects AND interfaces to support each domain object we concieved.

    A better solution, IMHO, is that you separate persistence/state from behavior-- such that you only have a single OrderDTO and ONE set of services supporting that DTO and persistence logic. When you need to introduce behavior and constraints anywhere in the system, you simply wrap the DTO and go--
  37. Constraints in the database[ Go to top ]

    I have tried this approach. Its nice but tedious when attempting to wrap all your data objects with a rich object - especially when dealing with entity relationships - where each rich wrapper is now responsible for creating a wrapper around a collection of its related entities - but one can choose to avoid this problem i.e. rich wrappers don't manage relationships but this pushes even more tediousness to the usecase controller.

    Have others had similar issues ?
  38. Constraints in the database[ Go to top ]

    have tried this approach. Its nice but tedious when attempting to wrap all your data objects with a rich object
    I've not tried it in practice but have read code that does and have thought about how things would look if I had - not a pretty sight. I prefer the service-per-domain-problem approach. These start at a coarse-grained level and use database-based DTOs as input/output data at first. As business requirements distill problem-oriented services are refactored, new service-speciffic (non-db based) DTOs are added to refine the existing ones, and even services are split up or re-combined.
    For instance here's how an instant messaging server would look: UserService, ChatService, SearchService. DTOs would be something like User, ChatMessage etc. As needs refine services are added, split or recombined. Also new DTOs are likely to appear, either database-based or not, for instance a List<User> initially serving as a search result might be changed to List<SearchResult> later on if we decide that we should search both users and archived conversations together (it's a rather stupid example indeed).
    The service implementations go about their thing in resolving the domain problems at hand. They can have global state or not. They manage database transactions themselves, delegate complex logic to specialised business "sub-services"; for instance if you could play hang-man with the server in a chat session this would not be implemented directly in the chat service, but as a layer, as a mix-in. Basically the front services coordinate transactions and agregate business logic, maintain state (if they're not stateless) and provide flow control, in terms of (message received) -> (begin) -> [delegate: offensive_words_filtering_subservice] -> [delegate_if_required: text_games_subservice] -> (persist) -> (commit) -> (notify) -> (ack). Or something like that.

    So, what do you guys think ?
  39. Constraints in the database[ Go to top ]

    I have tried this approach. Its nice but tedious when attempting to wrap all your data objects with a rich object - especially when dealing with entity relationships - where each rich wrapper is now responsible for creating a wrapper around a collection of its related entities - but one can choose to avoid this problem i.e. rich wrappers don't manage relationships but this pushes even more tediousness to the usecase controller. Have others had similar issues ?

    It's not that difficult when you say that your rich object only deals with rich objects-- so you have:

    // pulling up an order to work with it
    HeaderDTO hdr = hdrService.find(id);
    List<DetailDTO> dtls = dtlService.find(id);

    List<OrderLine> lines = OrderLine.wrap(dtls);
    Order order = new Order(hdr, lines);

    // work with order, adding a new line item
    Product prd = prdService.find(id);

    DetailDTO dtl = new DetailDTO(order.getHeader());
    dtl.assignProduct(prd);
    dtl.setQuantity(qty);
    dtlService.insert(dtl);

    order.getLines().add(new OrderLine(dtl));

    // done.
  40. Constraints in the database[ Go to top ]

    It's not necesarily a problem with EJB/entity. It's a problem for distributed systems as well.
    Take for instance a login/account_info example, IDL:
    module bank {
    struct account_info_dto {
    long id;
    long balance2dec;
    string currency;
    };
    interface account_info {
    long getId();
    long getBalance2dec();
    string getCurrency();
    };

    interface accounting {
    account_info_dto login(in string username, in string password);
    account_info login_with_if(in string username, in string password);
    };
    };

    Using login() you need 1 call to validate and get back account information for a client. Using login_with_if() you need 4, one for login_with_if() and 3 more getId(), getBalance2dec(), getCurrency().
    login_with_if() does not return a domain object, it returns an object reference. login() returns a struct, a Java bean, a POD. I fail to see how you do not have round-trip issues, this is a basic... issue.

    I've take a look at the link provided. And yes, that's where the struct/dto/array code lives - at boundaries, what I've been saying all along. The database is not a technology - it's a data system (amazingly it even has an S at the end to stand proof for it). Not much different than a remote client. With the database you talk in terms of data, never interfaces, business logic or whatnot. Data and services are all that's left at systems boundaries. Data is DTO, services are interfaces.
  41. Constraints in the database[ Go to top ]

    The database is not a technology - it's a data system (amazingly it even has an S at the end to stand proof for it). Not much different than a remote client. With the database you talk in terms of data, never interfaces, business logic or whatnot. Data and services are all that's left at systems boundaries. Data is DTO, services are interfaces.

    Yes it is a system. But not an external system when an application is modeled. If you've done any UML or the old precedure modeling the database is not shown as a system. In process modeling the store is within the system that uses it.

    So when my application retrieves non-transient objects from where they are peristed, a domain object is rehydrated with out the use of dto.

    In reference. login() - I do the same thing you do, only I return a domain object.
  42. Constraints in the database[ Go to top ]

    I do the same thing you do, only I return a domain object.
    Whatever that means. It either has struct semantics or not.
  43. Constraints in the database[ Go to top ]

    http://www.javadude.com/articles/
  44. Constraints in the database[ Go to top ]

    http://www.javadude.com/articles/

    I read that article and found it to be utter crap. Contract based design, especially by interfaces, only provides unecessary complexity. The author of the article says 'Interfaces are the Key', well interfaces ARE NOT LAYERS.

    If within my application, I have an Object representative of an Order in the database... what do I gain by putting an interface in front of it? If the database changes, both the interface AND the implementations will have to change with it.

    The number one tool in maintaining applications and easing others understanding of your code is being able to right click in the code and 'go to declaration'. If every time someone goes to a Domain Object's definition, they end up at an interface-- boy that's going to get annoying after a while. This is why I'm opting instead to create layers through delegation instead of interfaces. Hence my use of DTO's that are wrapped by BusinessObjects.
  45. Constraints in the database[ Go to top ]

    First of all I suggest that everyone in this thread read also the "Using annotations to replace getters/setters" thread, just a few lines above. Not everybody agreed with the article (including Cameron Purdy) but I tend to share much of the author's PoV.

    Perhaps we should also move this discussion to that thread, in an unusual attempt to remain on-topic.
    I read that article and found it to be utter crap. Contract based design, especially by interfaces, only provides unecessary complexity. The author of the article says 'Interfaces are the Key', well interfaces ARE NOT LAYERS.

    Interfaces help define layers by allowing a layer to describe itself to other layers without exposing their implementation details. Without interfaces, layers would be tightly coupled, and this would nullify their usefulness. Coupled layers == useless complexity. Layers decoupled through interfaces == a system that tolerates requirement changes.
    If within my application, I have an Object representative of an Order in the database... what do I gain by putting an interface in front of it? If the database changes, both the interface AND the implementations will have to change with it.

    Only if you have tightly coupled the user interface and the database (like in ol' good CRUD-based COBOL screen maps). The interface and implementation MUST change if user requirements change, not necessarily when the schema does. And do not tell me that you implement user requirements in the database.

    One of the key principles in a good J2EE architecture is "Do not make the application logic dependent on the DB schema". Perhaps this is the point you missed?
    This is why I'm opting instead to create layers through delegation instead of interfaces. Hence my use of DTO's that are wrapped by BusinessObjects.

    Ahem, if you read Gamma et al. [GoF], it clearly states that "Extension by delegation" is the key to a maintainable design, sure. The problem is that the book clearly states (read the other thread, too) that interfaces are the key to delegation and decoration. Delegator and delegated object must implement the same interface (extend the same abstract class in C++ - a very abstract class), or you end up with a mess of non-replaceable components. Are you wishing to contradict Gamma ? Though everybody should be free to contradict anybody, I suppose you must have a very strong point in order to do so and not lose credibilty.
  46. Constraints in the database[ Go to top ]

    Thanks Paulo,
     I just sat there flabbergasted not sure where to start replying.

     As for being able to go to the concrete class - if one is using Eclipse - Ctrl + T. Pretty easy and pretty cool. Doing it right (using Interfaces) use to be a pain but the Java IDEs have made it pretty simple (.Net on the other hand ... :( ).
  47. Constraints in the database[ Go to top ]

    Thanks Paulo,&nbsp;I just sat there flabbergasted not sure where to start replying.&nbsp;As for being able to go to the concrete class - if one is using Eclipse - Ctrl + T. Pretty easy and pretty cool. Doing it right (using Interfaces) use to be a pain but the Java IDEs have made it pretty simple (.Net on the other hand ... :( ).

    What it comes down to with developing business applications, is that with layering, changes will eventually occur, and when they do-- how many hurdles do you want to have thrown in your way?

    Either you accept the database for what it is up front, or you can spend your initial development and the lifetime of the application fighting it. The same goes for any other system or concern within your application. Putting interfaces in front of it isn't going to gain you anything. They are what they are and seek out other OO principals that are more efficient at covering your ass such as-- the Single Responsibility Principle, Liskov Substitution Principle, and Delegation and Composition.
  48. Constraints in the database[ Go to top ]

    Only if you have tightly coupled the user interface and the database (like in ol' good CRUD-based COBOL screen maps). The interface and implementation MUST change if user requirements change, not necessarily when the schema does. And do not tell me that you implement user requirements in the database. One of the key principles in a good J2EE architecture is "Do not make the application logic dependent on the DB schema". Perhaps this is the point you missed?

    Maybe it's the fact that I spend my time designing enterprise systems for a fortune 25 medical supplier-- but trying to build up useless layers on top of the db, instead of treating it as part of your application, is a waste of time and processing power and only adds useless complexity.

    This is why I've chosen the route of having a literal mapping of DTO's to database tables. Services are built upon the DTO's and their relationships-- no application requirements or logic introduced at this point.

    When one of our many applications now needs to work with that data, they just wrap the DTO returned from a DTO Service with a Business Object (introducing another layer) that the client application interacts with.
    Ahem, if you read Gamma et al. [GoF], it clearly states that "Extension by delegation" is the key to a maintainable design, sure. The problem is that the book clearly states (read the other thread, too) that interfaces are the key to delegation and decoration. Delegator and delegated object must implement the same interface (extend the same abstract class in C++ - a very abstract class), or you end up with a mess of non-replaceable components. Are you wishing to contradict Gamma ? Though everybody should be free to contradict anybody, I suppose you must have a very strong point in order to do so and not lose credibilty.

    GoF is a library of suggested patterns that should not be applied in all cases. If I was writing a public framework, then yes, I would use interfaces with the delegates. But we are talking about writing business applications where higher layers are built upon lower layers-- correct?

    So, if lower layers change, such as the DB schema, *some* chages will perculate up through the layers. Putting an interface in front of that object isn't going to gain you anything over a straight object.

    Example, we add an email field to an order header. In my system, you only need to add that field to the one DTO representative of that header. No changing multiple interfaces, or layers. Any objects that use that DTO immediately have that field available now to them and if they in turn want to expose it, they can just right click on the internal reference and 'generate delegate methods'. Done.

    Interfaces should only be introduced only when you need to provide MULTIPLE implementations. Trust me, I know what I'm talking about-- I had previously written an large application that basically followed that JavaDude article to a T, it's a pain in the ass to maintain changes. I'm much smarter and wiser now :-)
  49. Constraints in the database[ Go to top ]

    GoF is a library of suggested patterns that should not be applied in all cases.

    The "interfaces are the key" principle that I quoted is not in a particular pattern description but in the introduction part, which is the best collection of OO methodology advice written so far. Besides, you are stating that your architecture is built on the Decorator (Delegator) pattern, so you are in fact using one GoF pattern intensively (who doesn't?). My question, which received no answer, was, to be more explicit, "Do you think you know better than Mr. Gamma how the Decorator pattern is to be implemented?". A "yes" answer would be, of course, unquestionable.

    <blockqote>No changing multiple interfaces, or layers.
    The point is that you should not use multiple interfaces but multiple implementations at most. You use one interface (that may or may not map the DB schema on a 1-1 basis), and each layer can provide a different implementation, or use the common one. When one layer changes, changes do not necessarily propagate to the other layers. It is only the local implementation that changes, not the interface. And in simple situations all layers can use the same DTO or domain object. With your solution all layers must use the same implementation.
    Interfaces should only be introduced only when you need to provide MULTIPLE implementations.

    Since you cannot tell in the beginning whether the requirement for multiple implementations will eventually arise, at least in a non-trivial system, it is clear that interfaces are always needed if you want your system to be ready to accept requirement changes.

    Ok, from now on let's move this to another thread more related to the topic. Or better stop it altogether, since the debate is on the verge of entering the domain of impoliteness.
  50. Since you cannot tell in the beginning whether the requirement for multiple implementations will eventually arise, at least in a non-trivial system, it is clear that interfaces are always needed if you want your system to be ready to accept requirement changes.

    I think that on the contrary and in respect to the DTO + database issue, i.e. data changes, the need for multiple implementations is really not there. I mean fair enough, SAP runs on several databases, but most enterprise apps don't just change or swap that part.
    The need for interfaces arises at other levels in my oppinion. For instance you may want to replace the entire authentication layer, or add more implementations thereof. Services are definitely canditates for abstraction and formalisation.
  51. but trying to build up useless layers on top of the db, instead of treating it as part of your application, is a waste of time and processing power and only adds useless complexity.

    I second that. Overdesign is a menace.
    The data and the database are an integral part of the application. It's pointless to have anything more than a Facade in front of it, except for DTOs and (maybe) DTO service. I think the DTO service objects as Jacob calls them, or Domain Objects as other do are really necessary only when there's a certain level of richness and expresivity intrinsic to the data. From a design point of view I've seldom found this is the case, or simply preffered to go another route and instead build small problem-oriented service cores.
    For instance instead of having an AccountDTOBusinessObjectOrServiceOrDomainModelObjectOverAnAccount that handles currency exchange rates and conversions and fees I've chosen to implement the required operations as a small FeeService that uses the DTOs Account, CurrencyExchange and Fee to provide required transformations, skew exchange rates, compute profit and so on. This service core is used in the user-facing (where user is another application using the system) AccountService, that on a higher level provides operations such as transfer, getting the balance and so on, without exposing the intricacies of the currency-related code.
    In this scenario it does not make much sense to have speciffic objects ontop of each DTO, since for example the currency exchange and fee/profit thing does not belong anywhere. Also I do preffer having transaction code in a single unit of processing, not split at different depths in the layering.
  52. Chris, I know what DTO is and what it's good for. You said they're the worst anti-pattern ever, for Java at least. I didn't think that's a reasonable thing to say, that's all.The DTOs live at system borders - borders with the database, remote systems, GUIs and whatnot. What's inside these borders - it can very well be a procedural or domain driven design, I don't think that has any relevance on the use of DTO. What I'm saying is that maybe you wanted to warn against some problems but picked the wrong fight.

    Uh. I dind't say anything was the worst anti-pattern ever. Is this realy a fight? Maybe I did pick the wrong one. Hmmm.

    ,boz
  53. Uh. I dind't say anything was the worst anti-pattern ever.
    Uh. You actually did:
    Anemic domain models (aka DTOs) is IMHO the worst anti-pattern in the history of Java.
  54. In *real word* applications validations done using data in database. So IMHO this is very limited.
    Wow, what a pile of nonsense in a couple of words.
    May I ask why is it "pile of nonsense" (Yea, I misspelled *world*)
    I am not the author of the first reponse, but I dare to guess a few reasons: First, the example in the original article validates before going to the database. This can give better responsivity, better error messages, and better error handling. Plus the domain objects will be validated before you execute other business logic with them! Second, if you want this kind of validation in the database, you start treading into the territory of stored procedures and triggers, I am not sure that's such a nice place to be. Third, most *real world* java applications also validate in the domain objects. If you don't, you probably don't want to use domain objects in the first place, as they would at best be anemic, at worst error prone (if they have logic that must work despite validation errors). Anemic domain models (aka DTOs) is IMHO the worst anti-pattern in the history of Java.If you don't have domain object, this approach (and possibly J2EE) is not a good match for you. If you have domain objects, you'd want to validate in them, not (only) in the database.

    OK, most business applications are using database. Domain objects validations are using data from database. I did not mention stor procs. IMHO using annotaion it's similar to validations using javascript: sometimes useful, but limited to simple things.
  55. Constraints in the database[ Go to top ]

    The paper shows an interesting idea. But annotation based validation is a bit too static. For example, if MaxLength is now changed from 20 to 40. One have to recompile the code (let me know if I am wrong here).

    But if you store the maxlength in database, you can simply update the database without any code and/or deployment changes.

    Store constraint DATA in database, does not necessarily mean valid data IN database with stored procedures or trigger. One can and should still validate in Java code. If one knows the constraints are static and will not change, one can read the constraint condition into memory and cache it. And the Java code validates against the cached constraints, there is no performance penaltiese. If the constraints are sometime changes, the code should have mechanisms to refresh the cache by periodically pooling or event driven update. Thus the validation is against latest constraint data instead of the stale data.

    One approach, which I haven't tried myself, is may be use database to store constraint data but use AOP to validate the constraints. Define the point-cut for the place to be validate and write advice to centralize the validation.

    The pros :
    1. It centralize the logic of validation. it only has one place to maintain the code.
    2. If new validation is needed, one only add new point-cut to the advice.
    3. The object does not explicitly call out to validate against the constraints.

    The cons :

    It seems violating the OO principal: as each object should performs it's own validation.

    As I said, I havn't tried myself, just throw some idea out.
  56. Yes having constraint validation is very important but in general we should distinguish between “syntactic” validation and business logic validation. Usually the earlier we can apply this validations the better it is. Early validation can be done in most of the cases only for syntactic rules while for the business logic constraints the checking for consistency is possible only in the business tier or inside the database.
    One should also consider that detecting a constraint validation at some random point in the execution stack is futile. The places where this checking is done should be precisely specified ensuring that at that particular point proper recovery is possible. Such points are well defined in specialized frameworks (e.g. Struts Validator for input validation).
    I strongly support declarative approaches since they reduce code complexity but I don’t think that such generalization as mentioned here is required. For simple cases with little reuse is easier to write code than to plug in your own validator. Again the truth is rarely pure and never simple.

    Adrian
  57. Yes having constraint validation is very important but in general we should distinguish between “syntactic” validation and business logic validation.

    Presumably constraint annotations would allow arbitrary expressions, in which case semantic validation is treated the same as syntatic validation.
    Usually the earlier we can apply this validations the better it is.

    ...which is a reason why DB constraints are insufficient.
    One should also consider that detecting a constraint validation at some random point in the execution stack is futile.

    Effeil invariants contradict your claim.
  58. In *real word* applications validations done using data in database. So IMHO this is very limited.

    I agree that DB constraints are great. Constraints should be declarative when possible. Annotations are consistent with that.

    Of course the JRE has had extremely rich declared constraints for some time now, in the form of JAXB-bound XML Schema. A POJO/JAXB binding readily obviates custom constraint logic. Custom procedural validation should be a last resort. A benefit of annotations is not needing an external schema. Though an external schema could easily be transformed into annotations.

    Eiffel Design-By-Contract assertions are finally in reach. Ie pre/post/conditions and invariants. So the quality of Java programs goes up a notch.
  59. Yet another stupid idea. Now is the time for annotation hype and everybody will try to use it, properly or not.

    It looks like the hype about stupid and senseless scripting. Just invent something, spread the word and hope you will get famous.

    BE PRAGMATIC!
  60. Yet another stupid idea. Now is the time for annotation hype and everybody will try to use it, properly or not.It looks like the hype about stupid and senseless scripting. Just invent something, spread the word and hope you will get famous.BE PRAGMATIC!

    This is not stupid nor unpragmatic! Metadata approach to programming can save you a lot of time in some circumstances, although this is not applicable to every situation.
  61. This is not stupid nor unpragmatic! Metadata approach to programming can save you a lot of time in some circumstances, although this is not applicable to every situation.
    Annotation of any member of a class or to a Class,itelf,can be achieved through configuration settings. XML is more suitable for any attribute oriented programming.

    XML files used during deployment are likely to have support for hot-deployment, by many tools. Though the same is possible for java source code,it may not be supported by non-sophisticated tools.

    Regards
    Surajeet
  62. I think this would be a good idea with commons-validator.
  63. IMHO, the constraints shouldn't stay in the Java models. They are business logic, not intrinsic for JavaBeans.

    If we need to change the length constraints for strings frequently according to business strategies, must we recode and recompile related JavaBeans? It's better to stay as a runtime configurable property.
  64. Why couldn't you have the annotation apply a validation... that it looked up at runtime?
  65. IMHO, the constraints shouldn't stay in the Java models. They are business logic, not intrinsic for JavaBeans.If we need to change the length constraints for strings frequently according to business strategies, must we recode and recompile related JavaBeans? It's better to stay as a runtime configurable property.

    +1

    That's exactly what I think. Now the hype is to spread annotations like cheese on a pizza.
  66. Actually, I beat Anders Holmgren to the punch back in January with an article at OnJava.com:

    http://www.onjava.com/pub/a/onjava/2005/01/19/metadata_validation.html

    Funny, he brings up the same points as I did a couple months before.....
  67. Annotations are 2nd choice[ Go to top ]

    In my opinion annotations/pragma/macros is, why C++ is ugly and hard to learn. If you want simple validity constraints then they should reside in the language spec. What's bad about a new String(20) or an int(0..10000)?

    I know, Sun claims Java to be a "stable" language, but it isn't anyway.

    chris
  68. Annotations are 2nd choice[ Go to top ]

    In my opinion annotations/pragma/macros is, why C++ is ugly and hard to learn.
    Pragmas are compiler directives. There' needed. Get over it.
    Macros are fine as long as you know what you're doing. There's a crusade against them, that's cool with me because I've seen them used wisely and very efectively.
    And while I'm at it, C++ is the most advanced, beautiful and well thought out programming language - at least in the systems programming class. The templates alone are wonderous.
    And it's hard to learn if students are lazy, if it's taught like pascal++ or GUI development tool or just badly and because it's a very, and I mean *very* complex beast.
  69. Annotations are 2nd choice[ Go to top ]

    What's bad about a new String(20) or an int(0..10000)?

    I completely agree, and I've been missing that in Java since its inception. I became used to that kind of constructs when implementing and using a C++ library for ASN.1 in the early 90's and it seems like the obvious way to specify simple constraints. ASN.1 has such constraints built into the language, like INTEGER(0..99) and NumericString (SIZE (12)).

    Can anyone explain why this would not work in Java and possible negative effects?

    That said, I like the way the article covers the different aspects of the topic and accepting the current state of affairs in the Java world, annotations seems to be a good second choice.

    /Ragnar
  70. Annotations are 2nd choice[ Go to top ]

    What's bad about a new String(20) or an int(0..10000)?
    I completely agree, and I've been missing that in Java since its inception. I became used to that kind of constructs when implementing and using a C++ library for ASN.1 in the early 90's and it seems like the obvious way to specify simple constraints. ASN.1 has such constraints built into the language, like INTEGER(0..99) and NumericString (SIZE (12)).Can anyone explain why this would not work in Java and possible negative effects?That said, I like the way the article covers the different aspects of the topic and accepting the current state of affairs in the Java world, annotations seems to be a good second choice./Ragnar

    Something like this is quite possible if you combine Annotations and AOP. See my article at OnJava.com for concrete examples.

    Some people call annotations "hype", but if you're using XDoclet you're already using them. Sure people will abuse them, but they are a huge opportunity to simplify Java development. We see it as an opportunity to add pluggable syntax/keywords to Java. I think we should be encouraging articles such as this.

    Also, on a related note, Dean Wampler (formerly a Rational guy) has a project that combines Design By Contract, annotations, and AOP.

    http://www.contract4j.org/

    JBoss AOP has a similar project:

    http://www.jboss.org/wiki/Wiki.jsp?page=DesignByContractAspect

    Bill
  71. Do you test validation rules with JUnit?

    I mean such rules like maxLength(20), minValue(5), minSize(1), notNull(), unique() and so on.
  72. Do you test validation rules with JUnit?I mean such rules like maxLength(20), minValue(5), minSize(1), notNull(), unique() and so on.
    Can someone please quickly answer on this? Thanks.
  73. Not so cleanly, but helpful.

    I wander when other obvious ideas will get to
    thouse PR-writers. I assume that next article will be
    about some technique a year old.
  74. I have lived with annotations in .NET for several years and find it suprisingly hard to communicate its usage to team members and library users. I think annotations can be very useful, but the world is not ready, it seems.
  75. I think it's nice that everyone spills his/her guts on the proper place/method to validate. But I'm missing something crucial from a user perspective: suppose you do use annotations, you'll still need a way to make clear to the user that invalid data was entered. That's where you'll need either a new generic mechanism to capture the error/exception, or again some custom code. So where's the added value in using annotations?
  76. I think it's nice that everyone spills his/her guts on the proper place/method to validate. But I'm missing something crucial from a user perspective: suppose you do use annotations, you'll still need a way to make clear to the user that invalid data was entered. That's where you'll need either a new generic mechanism to capture the error/exception, or again some custom code.

    +1

    Catching the error is nothing, providing a user-friendly error message is everything.
    So where's the added value in using annotations?

    As for DB triggers and procs, I have seen and written validation code that raises custom DB exceptions, with understandable messages, used to maximum effectiveness. In a client-server environment this is probably the best way to validate. Maybe not in J2EE, though, since the SQL exception is unlikely to be rethrown to the presentation layer.

    If annotation validation includes a reference to a human-readable, localizable error message, then it is a definite help, since it can be used easily and with maximum effectiveness in the presentation layer.
  77. I think all constraints must be in database. UI or "input mask" can not manage data integraty, there are many interfaces to access database. User friendly messages are important, but it is not a good reason to ignore database constraints. I think it is better to duplicate validation or generate it from DB metadata than to break data.
  78. I think all constraints must be in database.
    If you make the db your integration point and don't want to duplicate logic then will will have too.
    I think it is better to duplicate validation or generate it from DB metadata than to break data.
    Not all constraints can be generated from metadata. Only RI and column types/sizes. There are many other things that would have to be enforced in triggers and stored procs. And hopefully no one has screwed up the model (that never happens).
  79. It is possible to generate "input validation" for "CHECK" constraints too. But this stuff can work for trivial cases only. It is common to have different "views" of data. "DATE" field in database and "year","month","day" fields in input form. I see no way to avoid duplication, if user needs cool error messages.
  80. If annotation validation includes a reference to a human-readable, localizable error message, then it is a definite help, since it can be used easily and with maximum effectiveness in the presentation layer.

    That is indeed a good use, but in some cases this can cause even more issues. I just think of i18n...
  81. Focusing on the actual suggestion here, I think that the major problem is that it's only addressing validation within the narrow focus of Java Code itself.
    What if my O/R mapping is metadata driven rather than based on beans / POJOs?
    What if I want to reuse the constraints across the Service and presentation layers?
    What if I want to provide site customisation of a constraint throughout the whole stack?

    I think that it's better to take a step back and view constrain modeling as a more abstract framework task that can be defined in a standard way and applied as required on a layer per layer basis. Commons Validator in Struts provides an implementation of this kind of approach, although its approaching it from the UI up which is probably not the best way.
    If we look for a good hook point for standardised validation then the proposal for abstracted Data Binding proposed in JSR227 would seem to fit the bill as it's a natural choke point in any case, and already has a rich description of the data.
  82. What if my O/R mapping is metadata driven rather than based on beans / POJOs?

    Interesting point. Could this be unified somehow? Could perhaps the Hibernate annotations be somehow re-used in the above way?

    Regards,
    Jens
  83. Reinventing the past[ Go to top ]

    I predict that if such constructs like

    @MaxLength(20)
    public String street;

    catches on then we'll later want to say

    @Constraint(StreetType)
    public String street;

    Why?

    Whenever you start constraining data you invariably run into typing. You'll want some nice way of saying "all names are size 20" or "all currency strings have this format" and so on. So the need arises to name common constraint sets the same thing, or you end up maintaining it in many places.

    That is why Pascal allows you to say stuff like:

    type
      arrayType = Array[1..20] of Integer;

    and C had typedef. Some dbs allow you to specify your own types too (if I recall properly).


    But this all makes me wonder why we don't just say:

    public Street aStreet;

    since the class Street would allow you to maintain such constraints on the data but using a more common OO technique.
  84. Validations and Annotations[ Go to top ]

    In general, i've found several things about validations:

    1. Validation at the time of property setting is problematic at best. It requires proper order of setting if you have dependent properties. Say for instance, you have a "startDate" and "endDate", which are properly set to "1/1/2005" and "2/1/2005", respectively. If you try to set the "startDate" to "2/2/2005" it will give you an error because the "end" date is after the start date, even though the very next call might set the start date to a later date.

    2. Using annotations for complex validations is extremely hard to achieve. Consider that individual objects may have custom validations which validate dependent fields against one another (ie. the startDate and endDate as above). This would require not only having to write the validation class, but writing an annotation class to go along with it, and having to somehow tie the two together (you could make an annotation on your annotation type which indicated a class which supplied the annotation behavior). In addition, if you change the available properties on the validation, you now have to change the annotation as well. Not exactly an ideal solution.


    Personally, I prefer the XML approach with the use of method interceptors. Basically, you create a validator declaratively (we're using spring), and then create a dynamic proxy object around your service. The dynamic
    proxy is given a method specification and a validator id
    which is to be called on a specific parameter at a given index.

    <bean id="MyValidator" class="..">..</bean>
    <bean id="_MyService" ...>...</bean>
    <bean id="MyService" class="ValidatorProxyFactoryBean">
       <property name="target"><ref bean="_MyService"></property>
       <property name="props">
          <entry key="insert"><value>0,MyValidator</value></entry>
       </property>
    </bean>

    Since it's easier to build up complex validators in XML than it is in annotations, this seems to be the much more effective approach. Yes, i would prefer using annotations (and in that case, my proxy above would simply find the validator from the object being validated, rather than from a bean in the file), but the lack of inheritance, and the restriction on not having multiple instances of an annotation on single element makes this extremely difficult.
  85. Validations and Annotations[ Go to top ]

    In general, i've found several things about validations:...
    I usually do object level validations. So I ask the object if it is valid or allow it to notify whoever cares that it is valid or invalid. So while a date object might have its own validation (is it a date), the object it is an attribute of might have other requirements of it.
  86. Validations and Annotations[ Go to top ]

    but the lack of inheritance, and the restriction on not having multiple instances of an annotation on single element makes this extremely difficult.

    Please expand on lack of inheritance. Personally, I don't care if an annotation cannot extend another annotation as IMO, I think it is better to just write another annotation. But, the fact that an annotation cannot be inherited by an overriding method is a problem. (@Inherit works on class annotations though).

    You can have multiple annotations on a single element by writing a wrapping array annotation, i.e.:

    public @inhterface EJBs {
      EJB[] value();
    }

    @EJBs({
        @EJB(name="foo"),
        @EJB(name="bar")
    })
    public class MyBean ...

    In the past year working with the JCP and such, I've found they are pretty receptive to feedback. We're now on the J2SE committee so, we'll put in our input on this. Its up to the rest of you to post feedback to the appropriate feedback mail lists.

    Bill
  87. Validations and Annotations[ Go to top ]

    but the lack of inheritance, and the restriction on not having multiple instances of an annotation on single element makes this extremely difficult.
    Please expand on lack of inheritance.

    I wrote an article for OnJava on this very same topic back in January and I do talk about how to provide intrinsic behavior to annotations and provide pseudo inheritance---

    http://www.onjava.com/pub/a/onjava/2005/01/19/metadata_validation.html

    Cheers!
  88. Reinventing the past[ Go to top ]

    .But this all makes me wonder why we don't just say:public Street aStreet;since the class Street would allow you to maintain such constraints on the data but using a more common OO technique.

    Because then we'd be called aStreet.toString() all over the place because the only time we don't want it to act like a string is when it's value is being set.
  89. Reinventing the past[ Go to top ]

    Annotations are elegant and the runtime introspection is definitely a good point for annotations but ....

    But here - we need to create all the Annotation classes - which is essentially the same as Java code, and then a Decorator around the Address class to do the validation based on reading at runtime the constraint annotations. Doesn't this seem like a lot of trouble and less clear ???

    Its seems a lot simpler and clearer to just do this ...

    public void setStreet(String street) {
      checkStreet(street);
      this.street = street;
    }

    private void checkStreet(String street) {
      Constraint.checkNotNull(string);
      Constraint.checkLength(10, 20);
    }

    Its clear, its OO refactorable to give you all the reuse you want. There is no runtime introspection - which has atleast one good point -> its faster.

    I don't think Annotations should be used where there is no container providing some specific service for the application - like a runtime mapping to a database or transaction, security etc. type management. If we have to write the annotations and then then define their types and their implementations - how is that different from writing it in Java ?

    Maybe a Constraint-Container would give some validity to this article .... Open Source folks .... ???
  90. Reinventing the past[ Go to top ]

    I don't think Annotations should be used where there is no container providing some specific service for the application - like a runtime mapping to a database or transaction, security etc. type management. If we have to write the annotations and then then define their types and their implementations - how is that different from writing it in Java ? Maybe a Constraint-Container would give some validity to this article .... Open Source folks .... ???

    I believe constraints/annotations should only be asserted based on some container's context-- such as using the bean within a persistence layer or web tier.

    http://www.onjava.com/pub/a/onjava/2005/01/19/metadata_validation.html
  91. Reinventing the past[ Go to top ]

    Annotations are elegant and the runtime introspection is definitely a good point ..
    Its seems a lot simpler and clearer to just do this

    ...public void setStreet(String street) {&nbsp;&nbsp;checkStreet(street);&nbsp;&nbsp;this.street = street;}private void checkStreet(String street) {&nbsp;&nbsp;Constraint.checkNotNull(string);&nbsp;&nbsp;Constraint.checkLength(10, 20);}

    Introspection/Annotations = Meta Data usable at runtime, compile time, deployment time...

    In your Java code, you would have the validations available only for the objects/POJOs. But since it's not meta data, you couldn't reuse it to

    - create validated DB-schemas (triggers..)
    - create HTML forms with Javascript that does client based validation
    - create import tools to load verified data from external sources...

    I don't think Annotations should be used where there is no container providing some specific service for the application - like a runtime mapping to a database or transaction, security etc. type management.

    That is one very important aspect, but the core is that annotations are meta data that can be used at different points in time (compile time, runtime, deployment).

    If we have to write the annotations and then then define their types and their implementations - how is that different from writing it in Java ?

    You would be right, if this information would only be needed once, but it is potentially needed in many situations (DB, Form, POJO, Load..).

    Its clear, its OO refactorable to give you all the reuse you want. There is no runtime introspection - which has atleast one good point -> its faster.

    BTW: introspection is very fast compared with DB operations, client interaction.., so that is not important in nearly all situations.

    Stephan
  92. It could be interesting to consider the merger of anotations as presented here and Design by Contract (see Java RFC 4449384: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4449383). Design by Contact(DbC) specifies that anotations might be validate prior to public call (pre-condition), on return (post-condition) or both (invariant).
    Also interesting is the fact that this implementation would be pretty close to has been implemented in iContract (see: http://www.javaworld.com/javaworld/jw-02-2001/jw-0216-cooltools.html).

    However, here are the interesting aspects I'd liked to point at:
    - DbC specifies that anotations should be part of inheritance (which makes sens as you don't want hers to brake parents behavior);
    - anotation might implies that contraints could be specifiy at the property level and apply by getters and setters.
  93. Reinventing the past[ Go to top ]

    The problem with Annotation or any code-based validation is CONTEXT. Do your objects always validate the same, no matter what context they're in? Well, lucky you, but that's often not the case. When I was designing the XWork Validation Framework, which is XML metadata driven, this was one of the major concerns. The XWork Validation Framework allows you to define validations for different contexts in different XML files:

    MyAction-validation.xml -> default validations
    MyAction-context1-validation.xml -> validations specific for context1 are added to the defaults
    MyAction-context2-validation.xml -> validations specific for context2,....


    This allows a lot of flexibility in validating objects differently based on where you are and what you're doing. Being able to use OGNL for expression validations is pretty powerful too...


    Annotations are elegant and the runtime introspection is definitely a good point for annotations but .... But here - we need to create all the Annotation classes - which is essentially the same as Java code, and then a Decorator around the Address class to do the validation based on reading at runtime the constraint annotations. Doesn't this seem like a lot of trouble and less clear ??? Its seems a lot simpler and clearer to just do this ...public void setStreet(String street) {&nbsp;&nbsp;checkStreet(street);&nbsp;&nbsp;this.street = street;}private void checkStreet(String street) {&nbsp;&nbsp;Constraint.checkNotNull(string);&nbsp;&nbsp;Constraint.checkLength(10, 20);}

    Sorry Sony, but this is horrible... What if this was a password field and its validation depended on the value of password2 (to make sure they're equal)? Per-property validations like this can't get the big picture because you don't know what other dependent properties have been set... Also, sometimes you're creating a new user and you want to check the 2 passwords, and sometimes you're editing an existing user and you don't want to make them enter the password again... Context is king.
    Its clear, its OO refactorable to give you all the reuse you want. There is no runtime introspection - which has atleast one good point -> its faster.I don't think Annotations should be used where there is no container providing some specific service for the application - like a runtime mapping to a database or transaction, security etc. type management. If we have to write the annotations and then then define their types and their implementations - how is that different from writing it in Java ? Maybe a Constraint-Container would give some validity to this article .... Open Source folks .... ???

    Umm... this is what an IoC container gives you... I know you're not a fan, but Spring can use annotations (or commons-annotations, which I like very much) as the pointcuts to apply AOP to your classes. It's very much declarative programming where you just specify some metadata about your Class and Spring picks it up to provide the right services transparently.
  94. Reinventing the past[ Go to top ]

    The context in this case is limited to the street property within the address object who is essentially the controller for this context. Every context has a controller - and so a larger scoped context and its validation will be managed by an equivalent larger controller. E.g. a usecase and its specific validations would be managed by a larger usecase controller.

    The validation depicted in the author's (and my) example is merely a constraint on the street restricted to the scope of an Address object's context.

    The validations of a larger context and its controller can be OO refactored for reuse just like the validations of a smaller context as I depicted.

    As a rule of thumb one would never squeeze the logic of a larger context into a smaller one - a clear design flaw.

    P.S I am not against Containers that provide useful services using Annotations or even XML based meta data including the services you suggest. I just don't see why IOC needs to be container managed - especially managing an entire object model relationship. IOC should be a standalone pattern just as any other pattern.
  95. I think declarative constraints are a great idea, because it separates the actual constraints from the implementation used for enforcing them.

    If I have something like

    @MaxLength(40)
    String name;

    ... I can use the same "@MaxLength(40)" annotation to drive web UI validation (e.g., ActionForm), SOAP request validation, WSDL/XSD generation, DB schema generation, even HTML forms themselves (<input maxlength=...>)

    Otherwise, there's a lot of cut-and-paste for all the references where I need to know that a particular field is 40 chars long.