View Poll Results: Which would you choose?

Voters
33. You may not vote on this poll
  • OpenSessionInView

    17 51.52%
  • DTO/VO

    8 24.24%
  • Other

    9 27.27%
Multiple Choice Poll.
Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 22

Thread: OpenSessionInView vs DTO/VO vs ?

  1. #11
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Apologies for my last post. After re-reading it I've just seen it was gibberish.

    At the minute I'm declaring transactions around my Service layer with a TransactionProxyFactoryBean. Anything that leaves here has to be eagerly fetched (as I'm using Hibernate, lazy loading issues) to ensure its available once the transaction has ended. Any object modified object that comes back into the Service has to be reattached. Does that make more sense, is that what your were suggesting?

    My other point was that the web tier can call methods on my object model that should really be hidden. I can make them default or protected, but is there a preferred solution here. A View interface might have been an idea if reflection wasn't involved. user.setFirstName ( "karl" ); is ok but user.enable (); would be inappropriate. I just wondered was there a common approach here.

  2. #12
    Join Date
    Feb 2006
    Posts
    164

    Default

    Quote Originally Posted by yatesco View Post
    I am sure you will agree Ben, that this is less then ideal, what about automated tests, regression tests etc.?
    Yes, I agree. Good point. Basically, I'm just saying don't use a layer without a good reason, coz there's a price to be paid for each layer. You bring up a good reason.

    Quote Originally Posted by yatesco View Post
    Debugging, I think, is usually misused. Now, *that* is heretical
    Interesting. I like hearing the "heretical" views of designer/developers who have been around the block a few times. It show that they are thinking out of the box. Since we all spend so much time debugging (or is it just me? )...can you expand on this, please, perhaps in a new thread?

    Ben

  3. #13
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by benethridge View Post
    Interesting. I like hearing the "heretical" views of designer/developers who have been around the block a few times. It show that they are thinking out of the box. Since we all spend so much time debugging (or is it just me? )...can you expand on this, please, perhaps in a new thread?
    Ben
    I actually cannot remember the last time I needed to use the debugger in production! I am quite strict with my test coverage though, so before the code gets out of my box I "know" that it does what I intend to do.

    Of course, whilst I am developing the tests I may use the debugger

    I think you are right, maybe a blog post is called for to justify my claims! Essentially I think that the "we can use a debugger" can (not does, only can) lead to people writing sloppy, unreadable, poorly documented* code. I also think the same thing about comments as well....now that is even more heretical !!!

    Maybe I am cynical, but I have worked in development teams when the code was so hideous that you needed to read the extensive comments and use the debugger (or work out the static tables yourself) to figure out what the heck was going on. I always ask my development team (when I had one) to write code that was self documenting....it is too easy to look at code and think, rather than refactoring to clarify, I will just comment it.

    *** I am not, of course suggesting that all comments are bad, but comments describing what code does is arguably a sign of poorly written code. Code should be self documenting as to what it does. The *intention* of the code, and pre reqs etc., are of course good candidates for comments, but "what does this code do?" .... read the code

    Essentially, if I (or any moderately skilled developer) cannot figure out what the code is doing from reading the source code (without comments) then there is something wrong with that code...even if it works, it is not acceptable. And yes, people initially hated working in my team with my strict checkstyle rules which failed the build, but eventually they all got on board and most found that they greatly improved because of it.....but there was much swearing and grinding of teeth. I seem to remember the words "anal retentive" being bounded about as well.....

    What on *earth* has this got to do with DTO/VO Man I need to shut up and go to bed!
    Last edited by Colin Yates; Oct 20th, 2006 at 06:29 PM.
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  4. #14
    Join Date
    Feb 2006
    Posts
    164

    Default

    Quote Originally Posted by yatesco View Post
    And yes, people initially hated working in my team with my strict checkstyle rules which failed the build, but eventually they all got on board and most found that they greatly improved because of it.....but there was much swearing and grinding of teeth. I seem to remember the words "anal retentive" being bounded about as well.....
    Ah, yes. The loniness of leadership .

    Seriously, you made some very good points there. Probably worthy of a blog or book chapter.

    Ben

  5. #15
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    I think a point missing from this debate is a characterisation of the different styles of applications. I think there is a natural measure of the "shape" of an application derived by comparing the "breadth" measured at the persistence layer in terms of number of entities/tables &c and the "height" in terms of the number of abstraction layers/tiers, and possibly also in terms of the "richness" or otherwise of the behaviour of the domain model itself.

    Some applications are *extremely* wide and low (a project I saw, for example, which consisted of an extremely complex schema designed to categorise and register occurrences of different kinds of cancer), and could be characterised as simply the persistence functionality dressed up in a palatable and coherent user interface. Other applications are quite tall and narrow (perhaps banking/payroll applications) with a rich cascade of interpretation from the highest layers to the lowest.

    Certainly for wide applications, the DTO pattern looks ridiculous. The model *is* the persistence model. On the other hand, I can quite easily imagine one or more "surrogate" models arising in "high" applications which are required to broker between the interpretations at different levels. Although I have to say that if a developer finds (as many have reported on this thread) that numerous slightly different representations of the *same* entity structure keep arising at different tiers (which in some cases "classically" represents the DTO pattern) that one has to query whether the design is really as high as it appears - if it is "implicitly" relying on the same representational structure at different levels it may as well do it explicitly and give up a pretence at embodying a rich domain model.

    Yes, it's very true however that while current persistence technologies (viz. Hibernate) are very "slick" in that they pretend to allow the selfsame POJOs to do duty at different levels of the architecture, it can't be avoided that persistence *semantics* are leaking out at the presentation layer even if through heroic Spring-Hibernate cooperation there is no visible dependence on the persistence tech's *code*. This is undeniably a serious architectural problem.

    In my view this reflects a need for yet more abstraction in the ways we talk about our domain model, and also a less enthusiastic application of Hibernate gimmicks (lazy relations/properties) - while recognising that in many practical cases these can offer the best design tradeoffs wrt. efficiency and transparency of the application. But as I see it the only long-term solution is to start dealing with presentation technologies that let one deal at a higher level of abstraction than raw Java code. Spring is already leading the way with its increased emphasis on declarative rather than programmatic constructs.

    Duplication of functionality at different layers of the architecture is *bad* - however a leakage of persistence semantics into the presentation layer is also *bad*. With current technologies and abstractions these remain two sorts of badness that the designer will need to trade off sensitively, with regard to the particular nature of the application. I don't think it is correct to give a blanket recommendation in this debate, with the technology at its current state of evolution :P

  6. #16
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    The original intent of this thread wasn't to come up with a silver bullet, it was just to provoke discussion about the architecture beyond the service layer.

    Quote Originally Posted by Bosmon View Post
    I think a point missing from this debate is a characterisation of the different styles of applications. I think there is a natural measure of the "shape" of an application derived by comparing the "breadth" measured at the persistence layer in terms of number of entities/tables &c and the "height" in terms of the number of abstraction layers/tiers, and possibly also in terms of the "richness" or otherwise of the behaviour of the domain model itself.

    Some applications are *extremely* wide and low (a project I saw, for example, which consisted of an extremely complex schema designed to categorise and register occurrences of different kinds of cancer), and could be characterised as simply the persistence functionality dressed up in a palatable and coherent user interface. Other applications are quite tall and narrow (perhaps banking/payroll applications) with a rich cascade of interpretation from the highest layers to the lowest.

    Certainly for wide applications, the DTO pattern looks ridiculous. The model *is* the persistence model. On the other hand, I can quite easily imagine one or more "surrogate" models arising in "high" applications which are required to broker between the interpretations at different levels. Although I have to say that if a developer finds (as many have reported on this thread) that numerous slightly different representations of the *same* entity structure keep arising at different tiers (which in some cases "classically" represents the DTO pattern) that one has to query whether the design is really as high as it appears - if it is "implicitly" relying on the same representational structure at different levels it may as well do it explicitly and give up a pretence at embodying a rich domain model.
    Completely agree with you. There isn't just one solution and there is implicitly a trade off between OSIV, DTO etc.... for every project. At some point you might even want to back track and introduce some DTOs into the mix that's fine.

    My overriding problem is, for the masses of people that are just building CRUD applications with some business logic in the mix, where should they start. I've seen some hugely over-engineering applications that do the simplest things. I've also refactored that complexity into something that is elegant and simple. The problem I always face though is "what do I do beyond the server layer"?

    One of the last projects I worked on, HAD to use DTOs. They were already there and we couldn't refactor the client interface to the system. They actually didn't cause that much pain, but I did find myself repeating logic, bad smell.

    I've also written applications where the domain is exposed out to the client, someone calls a method they shouldn't have do and all of a sudden we are up the creek.

    Quote Originally Posted by Bosmon View Post
    Yes, it's very true however that while current persistence technologies (viz. Hibernate) are very "slick" in that they pretend to allow the selfsame POJOs to do duty at different levels of the architecture, it can't be avoided that persistence *semantics* are leaking out at the presentation layer even if through heroic Spring-Hibernate cooperation there is no visible dependence on the persistence tech's *code*. This is undeniably a serious architectural problem.
    Again agree completely. Although things can be lazy loaded and its transparent, its still database access in the web tier, bad smell? I can program to interfaces all I like, but when the client is using reflection, that domain method gets called again.

    Quote Originally Posted by Bosmon View Post
    In my view this reflects a need for yet more abstraction in the ways we talk about our domain model, and also a less enthusiastic application of Hibernate gimmicks (lazy relations/properties) - while recognising that in many practical cases these can offer the best design tradeoffs wrt. efficiency and transparency of the application. But as I see it the only long-term solution is to start dealing with presentation technologies that let one deal at a higher level of abstraction than raw Java code. Spring is already leading the way with its increased emphasis on declarative rather than programmatic constructs.

    Duplication of functionality at different layers of the architecture is *bad* - however a leakage of persistence semantics into the presentation layer is also *bad*. With current technologies and abstractions these remain two sorts of badness that the designer will need to trade off sensitively, with regard to the particular nature of the application. I don't think it is correct to give a blanket recommendation in this debate, with the technology at its current state of evolution :P
    So we'll wait and see what happens......? Its not a good idea for a blanket recommendation, but for simple applications there must be a good rule of thumb. So many people are building the same kind of CRUD applications out there, there are simple solutions to simple problems.

    Hopefully more complex applications have more experienced and better equipped developers assigned to them. These people better understand the problems associated and therefore potential solutions. However, my experience so far says this isn't the case either.

  7. #17
    Join Date
    Feb 2005
    Location
    Cambridge, UK
    Posts
    37

    Default

    Quote Originally Posted by karldmoore View Post

    Completely agree with you. There isn't just one solution and there is implicitly a trade off between OSIV, DTO etc.... for every project. At some point you might even want to back track and introduce some DTOs into the mix that's fine.

    My overriding problem is, for the masses of people that are just building CRUD applications with some business logic in the mix, where should they start. I've seen some hugely over-engineering applications that do the simplest things. I've also refactored that complexity into something that is elegant and simple. The problem I always face though is "what do I do beyond the server layer"?
    Well, if we're specifically talking about folks starting out, assuming this is not an application of some unreasonable size, and with a relatively clear slate, I would consider to steer clear of DTOs.

    To me, DTOs represent a form of architectural desperation - an admission that with the tools and technologies available, the team can find *no* better way to avoid creating a leaky abstraction between the layers. Before one reaches for DTOs, one would want to try a whole heap of things (depending on the quality of the techs, and the skills of the team) -
    • For a start, you mentioned the #1 strategy higher up - make sure that any entities handed out of the DAO layer are "fully initialised", whatever this may mean. Unfortunately Hibernate doesn't make this terribly easy, manual calls to initialize() are unsightly and also not recursive. And of course the patch of non-laziness has to stop *somewhere*.
    • If you are moved towards OSIV or equivalent, try to adopt a view tech which has some sense. For example one couldn't expect a JSP-based app to behave very sensibly in the presence of unexpected exceptions. For contrasting reasons, JSF has poor exception semantics in of itself unless you spice up the mixture with something. Really today there is *no* excuse for ghetto-ising the view layer and make it the domain of code which isn't exception-safe - one of the common criticisms of OSIV, that it has the potential to raise unexpected exceptions, shouldn't be taken seriously, since correctly written Java code should be prepared to behave at least "decently" with exceptions from any function call. The C++ community takes these issues more seriously so far since they have the potential to bring down the app...


    Quote Originally Posted by karldmoore View Post

    So we'll wait and see what happens......? Its not a good idea for a blanket recommendation, but for simple applications there must be a good rule of thumb. So many people are building the same kind of CRUD applications out there, there are simple solutions to simple problems.
    Yup, the main force behind the DTO pattern is that it is *simple* and easy to explain. Doing the legwork to adopt other strategies will in general require more time and insight.

    An interesting point is that you never hear the Hibernate guys recommending DTOs. This is because they have the belief that the current semantics they endow their POJOs are "correct" and that people should just work with them. The fact that DTOs are rated so highly in your poll suggest that Hibernate chaps face at the very least an education gap, in addition to (I suggest) a functionality gap.

    Essentially what we *want* and need is that the DAO boundary form a demarcation layer in more than just the respects that Spring developers currently have power over - that is transaction/session opening semantics. The core problem is that Hibernate architecture is *closed* with respect to the proxying behaviour, whereas in a better scheme one would be able to use (Spring-style) declarative schemes to declare demarcation for lazy behaviour as well. For example, to wave a magic wand over the set of proxies that issue from the DAO and say "RIGHT then, from NOW, no further accesses to these objects can trigger any database activity". They would become, in my parlance, "Dead Beans" :P Much like with the currently supported Hibernate entity transitions (transient/detached/persistent &c) these references would be "re-enlivened" on passing back over the boundary.

    It is *this* deficiency more than anything which I see driving the use of DTOs - faced with a recalcitrant set of proxies, and in general an unaccommodating set of view technologies, it *has* become a reasonable engineering tradeoff to say to the two parties "sod it, I don't care what ridiculous 'live' semantics you have given these objects", and "sod it, I don't care *how* bad your exception handling/model traversal semantics are", "I'm going to do all the legwork of manually copying my domain model into pure beans just to stop you arses picking a fight". Certainly when working with the current front-runners in the form of Hibernate and JSF, one could quite easily make the argument this was a reliable strategy that made reasonable efficient use of developer resources.

    Long-term, the only way out of this is to improve Hibernate. Short-term, we need to try hard to design our models such that use of unnecessary lazy loading is minimised, and/or perform eager loading and/or use OSIV probably in conjunction with more reasonable view techs.

    Quote Originally Posted by karldmoore View Post
    I've also written applications where the domain is exposed out to the client, someone calls a method they shouldn't have do and all of a sudden we are up the creek.
    Quote Originally Posted by karldmoore View Post
    Again agree completely. Although things can be lazy loaded and its transparent, its still database access in the web tier, bad smell? I can program to interfaces all I like, but when the client is using reflection, that domain method gets called again.
    So yeah, these points are very interesting - re. the issue that the web tier needs a kind of "alternative" domain model. Now really one would like this to be "derived" from the primary domain model in some way, rather than having to start from scratch. I think my point earlier about the need for more declarative demarcation also goes here.

    To start with one needs to make the general observation that relying on progamming constructs to *forcibly* enforce protection restrictions is never going to work in the long run. If you are really finding developers persistently using reflective calls to access members not declared in APIs which you are passing them I suggest the issue would be better dealt with with some forms of social engineering (re, going down there and breaking their legs :P). And one has to ask *who* told them that these members were there :P

    But seriously, a quite productive way of "adjusting" domain models while in transit would be an progressive extension of the power of declarative demarcation boundaries. In addition to being able to wring out of Hibernate the ability to adjust the behaviour of its proxies, we might also want the ability to suppress/censor certain methods so they could *not* be called successfully, even reflectively. This is a bit belt-and-braces but the general strategy I think could be quite promising - it is an area where the Rubyites &c are well ahead of us with their ability to randomly decorate and undecorate objects on the fly with very little formality. But I believe we will catch up with them at the next bend.

    The problem is while we could *sort of* do this sort of thing with the techs provided by Spring-AOP, the real problem is that the "family jewels" are locked up in the form of the .hbm file which is currently the central repository of declarative information about the behaviour of the domain model. The fact that this is currently i) a one-shot deal which acts once when you start up the SessionFactory and ii) well behind Hibernate closed doors is the real impediment to getting this work done today. As both techs develop I hope and expect we will see an increasingly powerful convergence on this issue.

    There is some chat in this somewhat old thread http://forum.hibernate.org/viewtopic...=asc&st art=0 about a thing called "CarrierWave", which unfortunately seems somewhat defunct. "DynaDTO" is slightly more lively. But the point is this functionality *should* be achieved through an unbundling of Hibernate, not through piling things on top of it.

    Gosh, I have gone on about this a long time...
    Last edited by Bosmon; Oct 29th, 2006 at 05:42 PM.

  8. #18
    Join Date
    Jun 2005
    Posts
    4,230

    Default

    I'm voting for OSIV, but only on pragmatic grounds. Most of the time it is the first tool I would reach for, but there are times when I will be driven to a DTO. I think Bosmon has summarised well the way that the available technologies drive us to these decisions, ultimately to compromise in an imperfect world.

    I also think that maybe it is not just Hibernate that needs to be gutted. The semantics of the "declarative demarcation boundaries" would need to be available on both sides of the boundary - the view technology integrated as well as the persistence technology. The view has to know what properties are available for rendering, and ideally a small change to the view, e.g. to expose a new property, would be impossible without declaring that as a valid operation in a way that is immediately transparent to the persistence/transfer layer.

  9. #19
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Cheers for the reply, must have taken a while, it is appreciated. I can't really say much more than +1. There are lots of nice ideas in there and very good points!

    I think that DTOs are just an easy cop out for lots of people and the other extreme is just to reach for OSIV. You can get it working quickly and easily without really thinking about it. Eager loading where required would be a better starting point but I've seen lots of myCollection.size () code to get round this, mmmmm. I'm not sure at the minute there is a solution which ticks all the boxes, as david said its a compromise.

    I do like the idea of breaking legs social engineering as well. The problems I have here are its too easy to abuse the code. We can lock down the domain model by changing method scope, maybe try and use some aspect magic or someother voodoo. Sometimes though its not practical to stop my method being public, now the web tier has access. Although its not on the interface, people talk :-). Maybe some of the Rubyites ideas might be worth stealing.

    I do like lots of the ideas and hopefully we can catch up and progress. The idea of unbundling hibernate is also interesting, do you think Gavin and the boys would give up as you described it, the "family jewels"? :-)

    Thanks for spending some time on this, I've met so many people who just don't have any real answers. Its good to get some informed discussion.
    Last edited by karldmoore; Oct 30th, 2006 at 03:01 AM.

  10. #20
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by karldmoore View Post
    I do like the idea of breaking legs social engineering as well. The problems I have here are its too easy to abuse the code. We can lock down the domain model by changing method scope, maybe try and use some aspect magic or someother voodoo. Sometimes though its not practical to stop my method being public, now the web tier has access. Although its not on the interface, people talk :-). Maybe some of the Rubyites ideas might be worth stealing.
    IME it is impossible to stop idiots being idiots. I have come to the conclusion that trying to butcher the API to prevent plonkers being plonkers is just never going to work. The API should expose the rich contract of the object in question. If different layers have different views of the same model, then why not use different interfaces, all implemented by the same object (ReadOnlyUser, ModifiableUser etc.)?

    I am not saying that the API should expose every possible method, rather it should expose every *relevant* method for the usage of the object at that moment in time, regardless of the developer's skill.

    And while I don't quite believe in "breaking legs social networking" I do believe that code is a very powerful tool, and code deserves to be treated with respect....if developer's don't get that, then sure, they need training up
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •