Opinions on the Transfer Object pattern

http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html

The URL given is Sun's writeup on the Transfer Object pattern. If I understand it correctly, it recommends copying data from persistent entity objects to POJOs that can be passed to the presentation layer.

It seems like this would create a situation where you basically have parallel code trees for the entities and the transfer objects. This seems a little odd to me. What do others think?

[487 byte] By [jds@ku.edua] at [2007-10-3 11:05:34]
# 1

To add to this question...

I've seen more than one JSF example web app that directly used Java EE 5 entities in the JSF pages. Doesn't this go against the purpose of the Transfer Object pattern?

I'm confused. Is passing persistent entities to the presentation layer a bad thing or an acceptable coding practice?

jds@ku.edua at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 2
Does anyone know of an example of a successful use of the Transfer Object pattern? Does it show up anywhere in the Pet Store 2.0 app?
jds@ku.edua at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 3
> I've seen more than one JSF example web app that> directly used Java EE 5 entities in the JSF pages.What are Java EE 5 entities?
GhostRadioThreea at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 4
Java EE 5 entities are persitant beans returned by an EntityManager instance. It's the Java EE 5 container-managed persistence mechanism.
codebooka at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> http://java.sun.com/blueprints/corej2eepatterns/Patter

> ns/TransferObject.html

>

> The URL given is Sun's writeup on the Transfer Object

> pattern. If I understand it correctly, it recommends

> copying data from persistent entity objects to POJOs

> that can be passed to the presentation layer.

That doesn't sound correct to me - I suppose it means what you mean by "persistent entity".

Normally you would either use entity beans or POJOs. One or the other of those represents your DAO layer. A DTO (transfer object) would be used to pass data out of the DAO layer.

>

> It seems like this would create a situation where you

> basically have parallel code trees for the entities

> and the transfer objects. This seems a little odd to

> me. What do others think?

I use DTOs to transfer data between layers. Databases is just one layer that it can be used by.

If you have "parallel" code trees then it would normally suggest to me that you are doing something wrong.

A layer uses the DTO itself.

jschella at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 6
> > I'm confused. Is passing persistent entities to the> presentation layer a bad thing or an acceptable> coding practice?I don't know what a "persistent entity" is.I know that even on very small apps I would still have a DAO layer and
jschella at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 7
By "persistent entity" I would be referring to "entity beans" as defined by the Java EE 5 spec.
codebooka at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 8
> By "persistent entity" I would be referring to> "entity beans" as defined by the Java EE 5 spec.By definition you can't use those in a true presentation layer - they can only live on the server.You could however use them in a servlet.
jschella at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

> By definition you can't use those in a true

> presentation layer - they can only live on the

> server.

>

> You could however use them in a servlet.

Isn't a servlet a portion of a true presentation layer? It produces the HTML. And in that sense, JSF, JSPs and servlets all serve the same purpose.

codebooka at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

> > By definition you can't use those in a true

> > presentation layer - they can only live on the

> > server.

> >

> > You could however use them in a servlet.

>

> Isn't a servlet a portion of a true presentation

> layer? It produces the HTML. And in that sense,

> JSF, JSPs and servlets all serve the same purpose.

Which is why I said 'true'.

And servlets at least can serve other purposes than presentation. If applets are being used then servlets won't be doing presentation at all.

jschella at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

> Isn't a servlet a portion of a true presentation layer?

Maybe, but I consider it more web controller.

> It produces the HTML.

No one should be writing servlets that produce HTML directly. You can consider JSPs HTML factories. Since we know that JSPs are compiled into servlets before being compiled into byte code I suppose you might argue that servlets produce HTML.

> And in that sense,

> JSF, JSPs and servlets all serve the same purpose.

JSF? No. It's a web MVC framework that happens to be comprised of servlets and JSPs. It's in the same camp as Struts, Spring MVC, WebWork, and the thousands of other web MVC frameworks out there.

%

duffymoa at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 12

I think the Transfer Object and TO Assembler patterns are good ones. Best when you are using distributed web servers and EJB's. The Assembler assembles a logical record (can be from more than one table) that is used by the client. The TO is used by the client as a POJO, as opposed to making fine-grained requests to an entity bean. In EJB's prior to 3.0 (I don't know if the 3.0 standard fixed this or not), every get() method could potentially result in a bean being serialized and sent over to another JVM - assuming distributed app servers were being used.

bayareadavea at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

Let me see if I'm following you correctly.

In your experience (prior to EJB 3 at least), if I had a MyBean object that was passed to me by an EJB container (remote server), when I called myBean.getSomeValue(), the bean would actually get serialized, sent back to the server, the get request processed and the result serialized and sent back to me?

Wow. That seems crazy.

Does anybody know if EJB 3.0 entities have this problem? If I ask a remote session bean to getPerson() and it returns a Person object to me, when I call person.getName() will this incur network traffic back to the EJB container? If not, does the EJB 3.0 entity fulfill the role of the Transfer Object? It seems like it would.

codebooka at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 14
Fowlers First Law of Distributed Object Design: Don't distribute your objects [Fowler PoEAA]
georgemca at 2007-7-15 13:28:12 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> Let me see if I'm following you correctly.

>

> In your experience (prior to EJB 3 at least), if I

> had a MyBean object that was passed to me by an EJB

> container (remote server), when I called

> myBean.getSomeValue(), the bean would actually get

> serialized, sent back to the server, the get request

> processed and the result serialized and sent back to

> me?

>

> Wow. That seems crazy.

That isn't how it worked on the first EJBs that I worked with and I believe that was 1.0.

jschella at 2007-7-21 13:38:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 16

> when I [ call ] myBean.getSomeValue(), the bean would actually get

> serialized, sent back to the server, the get request

> processed and the result serialized and sent back to

> me?

Sorry for introducing the confusion. I went to the Core J2EE page (which was written before EJB 3.0), which describes the impetus behind the Transfer Object pattern this way:

Every method call made to the business service object, be it an entity bean or a session bean, is potentially remote. Thus, in an Enterprise JavaBeans (EJB) application such remote invocations use the network layer regardless of the proximity of the client to the bean, creating a network overhead. Enterprise bean method calls may permeate the network layers of the system even if the client and the EJB container holding the entity bean are both running in the same JVM, OS, or physical machine. Some vendors may implement mechanisms to reduce this overhead by using a more direct access approach and bypassing the network.

As the usage of these remote methods increases, application performance can significantly degrade. Therefore, using multiple calls to get methods that return single attribute values is inefficient for obtaining data values from an enterprise bean.

> Does anybody know if EJB 3.0 entities have this

> problem?

Then, I found this in a Sun developer article:

Because EJB 3.0 architecture no longer uses Container Managed Persistence (CMP) entity beans, fine-grained remote access of entity beans is no longer an issue. Entities are now Plain Old Java Objects (POJOs)

Also, the same article discusses using EJBs and session facade design pattern - see http://java.sun.com/developer/technicalArticles/ebeans/ejb_30/#entity

bayareadavea at 2007-7-21 13:38:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 17

> > when I [ call ] myBean.getSomeValue(), the bean

> would actually get

>

> Sorry for introducing the confusion.

>

> Every method call made to the business service

> object, be it an entity bean or a session bean, is

> potentially remote. Thus, in an Enterprise JavaBeans

> (EJB) application such remote invocations use the

> network layer regardless of the proximity of the

> client to the bean, creating a network overhead.

> Enterprise bean method calls may permeate the network

> layers of the system even if the client and the EJB

> container holding the entity bean are both running in

> the same JVM, OS, or physical machine. Some vendors

> may implement mechanisms to reduce this overhead by

> using a more direct access approach and bypassing the

> network.

>

> As the usage of these remote methods increases,

> application performance can significantly degrade.

> Therefore, using multiple calls to get methods that

> return single attribute values is inefficient for

> obtaining data values from an enterprise bean.

That is something that one can do.RMI had the same problem and some people originally implemented it that way (for RMI.) Doing it that way was a obvious no-no for anyone with RPC experience as well.

Once EJB arrived that rule for RMI was fairly well established and published.

jschella at 2007-7-21 13:38:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 18

> By "persistent entity" I would be referring to

> "entity beans" as defined by the Java EE 5 spec.

Hi,

Probably with Java Persistence objects, the new "persistent entity" in Java EE 5, the Transfer Object Pattern is not really needed. You can use Java Persistence objects as POJOs (plain old java objects) and they can also be managed and do your persistence work for you. You can also make them serializable so they can be used for remoteness

The transfer object pattern may not be needed much in Java EE 5. It was needed in some cases in previous versions of java EE since the web tier (and other places in the system) might want POJOs but the entity beans were components and didnt make nice pojos so often you needed another object that copied some of the data in entity components into a nicer object, sort of a pain IMO.

Java Persistence APIs let you use your entities as objects and you get a more nature design.

hth,

Sean

seanbrydona at 2007-7-21 13:38:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 19

> Probably with Java Persistence objects, the new

> "persistent entity" in Java EE 5, the Transfer Object

> Pattern is not really needed. You can use Java

> Persistence objects as POJOs (plain old java objects)

> and they can also be managed and do your persistence

> work for you. You can also make them serializable so

> they can be used for remoteness

So, what do you do when you want to use a 'persistent entity' remotely, but don't want to populate/fetch all relationships (and their relationships, and their relationships, and so on)? Do you simply make a development rule: "Call the session bean when you need to fill in the relationships, if ever", or something like that?

codebooka at 2007-7-21 13:38:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 20

> > Probably with Java Persistence objects, the new

> > "persistent entity" in Java EE 5, the Transfer

> Object

> > Pattern is not really needed. You can use Java

> > Persistence objects as POJOs (plain old java

> objects)

> > and they can also be managed and do your

> persistence

> > work for you. You can also make them serializable

> so

> > they can be used for remoteness

>

> So, what do you do when you want to use a 'persistent

> entity' remotely, but don't want to populate/fetch

> all relationships (and their relationships, and their

> relationships, and so on)? Do you simply make a

> development rule: "Call the session bean when you

> need to fill in the relationships, if ever", or

> something like that?

You can mark the fields you dont want fetched as lazy fetched so you only have the data you want.

I am guessing you are talking about a remote scenario where a client is calling a session bean thru RMI-IIOP? In this case, it might be better tio fetch eagerly the whole POJO and all the related data and have a coarse grained communication. You don't want to do fined grained access to the session bean over a network where you would be getting individual fields on each call.

Note, Java Persistence objects can be in several states, one of them is "managed" and one of them is "detached". In detached mode they are POJOs. When you want them managed(data fecthed or pushed or merged with DB) they are managed.

not sure that helps,

Sean

seanbrydona at 2007-7-21 13:38:51 > top of Java-index,Other Topics,Patterns & OO Design...
# 21

> I am guessing you are talking about a remote scenario

> where a client is calling a session bean thru

> RMI-IIOP? In this case, it might be better tio fetch

> eagerly the whole POJO and all the related data and

> have a coarse grained communication. You don't want

> to do fined grained access to the session bean over

> a network where you would be getting individual

> fields on each call.

The problem is that this would result in fetching pretty much the entire database. Where do you draw the line. I think we're going to draw the line at collection valued relationships. We'll eagerly load all non-collection valued relationships (which I think is the default JPA behavior) and not load the rest (Sets, Lists, etc). When those are needed, we'll make a call to another bean or another web service.

codebooka at 2007-7-21 13:38:51 > top of Java-index,Other Topics,Patterns & OO Design...