Java EE design advice for a re-designed DB app
I'm currently tasked with rewriting a legacy DB app in Java. The original was written in Delphi. It worked great for a number of years, but the powers that be have recently decided to redesign and rewrite it in Java. Basically I just have the same set of business requirements as the original did.
Overall, the app is a desktop GUI application that helps track contents of a natural history museum collection. The collection contains a bunch of specimens (dead animals) collected all over the globe at various times over the last 200 years. Multiple users (1 - 10 uesrs) will have to have access to the data at the same time. I also have to provide a nice Swing GUI for it.
Here's my question: Is this the type of app that lends itself to a Java EE design? I'm imagining using a Java EE app server that connects to the DB. The app server would provide DB access, producing entity beans, as well as managing a number of session beans (EJBs) that implement the business logic (security, user management/session management). I would also have a Swing GUI that would connect to the beans remotely. This sounds like it would help me keep a good disconnect between the UI layer (Swing), the business logic (EJBs), and the data layer (entity beans accessed using the Java Persistance API). Does this sound reasonable? I'm a veteran Swing developer, but not a seasoned Java EE developer/designer.
Also, if I use this architecture, I can imagine one issue that I might run into (I'm sure there are many others). I can imagine that I would want to retrieve the entity beans (lets say mypackage.MyPersonBean) through some call to an EJB, and then use the bean in some rendered Swing component. What happens when the Swing component needs to access the results of MyPersonBean.getAddresses() if the addresses are lazy loaded?
As you can probably tell, I really have more than one design question here. Help/comments about any of this is greatly appreciated.
> I'm currently tasked with rewriting a legacy DB app
> in Java.
I also am working on developing a DB app in Java. Some of the questions you brought up are questions that I'm dealing with as well.
> Here's my question: Is this the type of app that
> lends itself to a Java EE design?
This app seems like a perfect candidate for an EE design. I'm currently reading "Beginning EJB 3 Application Development" (APress). In the first chapter about session beans, the authors describe a "3-Tier Architecture with Rich Client". A DB app with a Swing front-end that requires multiple concurrent users seems like a perfect example of what the authors are talking about. (I haven't read the whole book yet, so I can't say that I'm totally certain about this.)
> Also, if I use this architecture, I can imagine one
> issue that I might run into (I'm sure there are many
> others). I can imagine that I would want to retrieve
> the entity beans (lets say mypackage.MyPersonBean)
> through some call to an EJB, and then use the bean in
> some rendered Swing component. What happens when the
> Swing component needs to access the results of
> MyPersonBean.getAddresses() if the addresses are lazy
> loaded?
In my app, I have a list of entity beans (for example java.util.List<MyPerson>) that serves as a data model for a JTree. I'm running into the same issue. If I click on a node, to expand it and show the children of the MyPerson instance, I have to hit the DB again to get the children. So, I either have to write a method getChildren(MyPerson parent) on some EJB that starts a transaction, etc, or I have to load all the children before I ever return the MyPerson instance. That isn't a good solution since that would really mean loading ALL MyPerson records in the DB since a user could open ALL the nodes. (Right now, my app isn't using entity beans per se, but we do use Hibernate 3, only outside of an EJB container context.)
consider spring or other 'lightweight' frameworks also
> Here's my question: Is this the type of app that
> lends itself to a Java EE design?
Sounds OK.
> I'm imagining
> using a Java EE app server that connects to the DB.
> The app server would provide DB access, producing
> entity beans, as well as managing a number of
> session beans (EJBs) that implement the business
> logic (security, user management/session
> management).
That's pretty typical, I think. Just realize that this isn't a design. It's not the beginning of the design. It's not even a gleam in the eye of the father of the design. You've got a lot more work to do before you will have anything that is meaningful.
> I would also have a Swing GUI that
> would connect to the beans remotely. This sounds
> like it would help me keep a good disconnect between
> the UI layer (Swing), the business logic (EJBs), and
> the data layer (entity beans accessed using the Java
> Persistance API). Does this sound reasonable? I'm
> a veteran Swing developer, but not a seasoned Java
> EE developer/designer.
I actually would suggest that you step back a second and design this part first without regard for where the data will come from or how you will get it. Once you have that figured out, you will be in a solid position to finish a sucessful and clean design. You might even decide that you don't need an app server and EJB at all. Keep your options open. EJB 3 is brand new and while fairly well regarded, largely unproven. The previous versions of EJB have become Sun's albatross, so take all this stuff with a grain of salt.
> Also, if I use this architecture, I can imagine one
> issue that I might run into (I'm sure there are many
> others). I can imagine that I would want to retrieve
> the entity beans (lets say mypackage.MyPersonBean)
> through some call to an EJB, and then use the bean in
> some rendered Swing component. What happens when the
> Swing component needs to access the results of
> MyPersonBean.getAddresses() if the addresses are lazy
> loaded?
As mchan mentioned, you might want to consider hibernate or another framework (hibernate is the most popular.)I have my own issues with hibernate and the whole POJO craze but I'm on the lunatic fringe with these thoughts, as far as I can tell.
And like m.cotton said, it is best to ignore daFei completely.
What the heck happened? There were about 10 replies to this message. Suddenly, I came back to the thread and found that only 3 were still here?
Here's a bunch of the stuff from the last reply, which I wanted to comment on, but it was gone.
--
Post from dubwai that seems to have disappeared.
--
User dubwai posted the following message
> > Which of the following
> > ideas is the best one to work with?
> >
> > 1. Swing GUI calls a method on a EJB3 session bean
> > (getData()) which returns a List<MyEntity> (MyEntity
> > is a EJB3 entity bean class). I use the List as a
> > TableModel to display the JTable. When a user
> > double-clicks a row, I call a method on a session
> > bean (getAssociatedRecords()) which handles all lazy
> > loading of associated data.
> >
> > 2. Swing GUI calls a method on a EJB3 session bean
> > (getData()) which returns a List<MyDTO> (MyDTO is a
> > transfer object holding data from a MyEntity object).
> > I use this list of DTOs as the basis for my
> > TableModel.
Can I choose 'none of the above'?
There is absolutely no reason you should have gui code calling session beans. You are making two huge mistakes here. 1. Don't put any logic in gui code. Guis should be dumb. Along the lines of what GhostRadio was saying, a really good design would be usable in a web based app and in a swing based one. 2. Like I was saying before, you should not be binding the data model to the underlying technology used to retrieve and update the database.
Here's an approach that I used that was successful:
Create a data management abstraction. An abstract factory or set of simple factory methods usually. So you'll have a method like getFoo(), that returns a Foo. Now, to lazy load the children inside of Foo, you build Foo so that it's children are stubs of markers that signify that the data has no yet be retrieved. So lets's say Foo has a method getBars() that returns a list of bars. When Foo.getBar is called, it evaluates whether the Bars have been retrieved (e.g. the underlying list reference is null), which then uses the data management abstraction to retrieve the bars and populate the list.
From the code calling this, it's transparent. It calls getBars and gets some Bars. It may take a little while but that's assumed in any lazy loaded solution.
This approach allows for some enhancements, too. You can create a thread that retrieves the children of Foo (e.g. bars) incrementally after the Foo is returned to the caller. Often you can load the bars in the time it takes the user to click around to the point where they are needed or at least be partly done. This will make the app seem very fast to the user because they get the Foo very quickly (because you didn't load the chidren) and then the bars really quickly (because you loaded them during user 'think-time').
Now I will comment on dubwai's post, which was deleted somehow.
> Don't put any logic in gui code.
> Guis should be dumb.
I totally agree with this. When I started writing GUI action handlers that had business and data model code in them, I started getting a little worried that I was putting together a total piece of garbage.
>Along the lines of what
> GhostRadio was saying, a really good design would be
> usable in a web based app and in a swing based one.
That's what I was hoping for. The data model shouldn't know or care what type of presentation layer is present, if any. The presentation layer shouldn't know or care where the data is coming from.
> Here's an approach that I used that was successful:
>
> Create a data management abstraction. An abstract
> factory or set of simple factory methods usually. So
> you'll have a method like getFoo(), that returns a
> Foo. Now, to lazy load the children inside of Foo,
> you build Foo so that it's children are stubs of
> markers that signify that the data has no yet be
> retrieved. So lets's say Foo has a method getBars()
> that returns a list of bars. When Foo.getBar is
> called, it evaluates whether the Bars have been
> retrieved (e.g. the underlying list reference is
> null), which then uses the data management
> abstraction to retrieve the bars and populate the
> list.
I was thinking the same thing, but don't have a successful experience to validate my gut feelings. Here's my only suggestion (which dubwai could hopefully confirm or correct): write your entity classes/data model classes with no knowledge of lazy-loading etc. Then subclass them, overriding just the getChildren() type of methods and build the lazy-loading knowledge into the subclass. When the GUI asks for an object in the getData() call, hand them a subclass object, but don't let them know it. In other words, have the method "public DataClass getData()" return a SubDataClass object. The caller will only know that they received a DataClass object, but lazy-loading awareness will be built into it. This way, the lazy-loading stuff is completely transparent to the caller but you still have simple data classes that can be used outside of a lazy-loading context. It's also possible to use this method if you need to add transparent lazy-loading to classes that you aren't the author of. (Only classes that have been tagged 'final' or have 'final' public methods would be beyond this method's reach.)
> This approach allows for some enhancements, too. You
> can create a thread that retrieves the children of
> Foo (e.g. bars) incrementally after the Foo is
> returned to the caller. Often you can load the bars
> in the time it takes the user to click around to the
> point where they are needed or at least be partly
> done. This will make the app seem very fast to the
> user because they get the Foo very quickly (because
> you didn't load the chidren) and then the bars really
> quickly (because you loaded them during user
> 'think-time').
I love this idea. I'm hoping to code this into my GUI app soon.
> What the heck happened? There were about 10 replies
> to this message. Suddenly, I came back to the thread
> and found that only 3 were still here?
This is common of late in any thread where daFei is involved. They truncate the thread.
In that post (thanks for reposting it) I wrote "stubs of markers" when it should be "stubs or markers". I'm not sure if it was an obvious typo or not.
> I was thinking the same thing, but don't have a
> successful experience to validate my gut feelings.
> Here's my only suggestion (which dubwai could
> hopefully confirm or correct): write your entity
> classes/data model classes with no knowledge of
> lazy-loading etc. Then subclass them, overriding
> just the getChildren() type of methods and build the
> lazy-loading knowledge into the subclass.
More or less, yes. Don't over-think it, though. If you define your basic data 'types' as interfaces, you don't need to get into complex type hierarchies or multiple versions of the types unless that becomes necessary and if it does, the changes should not affect the presentation layer.
Since you are on-board with this and I think you are completely following, there is a technique for the lazy loading that you can use here.
In the case where it's a one-to-one relationship, you can do the lazy-loading by creating a simple wrapper class for the child object. This class will have a reference to either null or a filled in Object. This is a little more OO because the Object is taking care of itself. Whether this abstraction is useful to you, you will have to decide.
In the case of a one-to-many relationship, you can create a custom Collection (List or Set) that manages the stub loading. If you make a generic abstract version and subclass it for the different child types, you might be able to reuse a lot of the data retrieval code. You can do the same thing with the wrapper too.
I will caution you to try to keep it as simple as you can without painting yourself into a corner. Only do things that you are going to use now and write things so they can be expanded upon later. Reducing coupling is a core technique for that.
> When the
> GUI asks for an object in the getData() call, hand
> them a subclass object, but don't let them know it.
> In other words, have the method "public DataClass
> getData()" return a SubDataClass object. The caller
> will only know that they received a DataClass
> object, but lazy-loading awareness will be built
> into it. This way, the lazy-loading stuff is
> completely transparent to the caller but you still
> have simple data classes that can be used outside of
> a lazy-loading context.
Yes this is the idea, but don't write the other versions until you need them.
> It's also possible to use
> this method if you need to add transparent
> lazy-loading to classes that you aren't the author
> of. (Only classes that have been tagged 'final' or
> have 'final' public methods would be beyond this
> method's reach.)
Yes, you can use the wrapper approach above but if the author of that class made a lot of unecessary assumptions you might have trouble.
> > This approach allows for some enhancements, too.
> You
> can create a thread that retrieves the children of
> Foo (e.g. bars) incrementally after the Foo is
> returned to the caller. Often you can load the
> bars
> in the time it takes the user to click around to
> the
> point where they are needed or at least be partly
> done. This will make the app seem very fast to the
> user because they get the Foo very quickly (because
> you didn't load the chidren) and then the bars
> really
> quickly (because you loaded them during user
> 'think-time').
>
> I love this idea. I'm hoping to code this into my
> GUI app soon.
I would advise that you get the main lazy-loading working without this (keep in mind when writing the code) and do it once you are sure you will finish on time.
Would it be prudent of me to post a summary of the previous messages, except for the ones from daFei? What's with that guy anyway? I think I have most of them in my browser cache or email notifications.
> Would it be prudent of me to post a summary of the> previous messages, except for the ones from daFei?Any that you found to be helpful or on-topic would be fine to repost, I think.> What's with that guy anyway?It's one of the forum's great
> > Don't put any logic in gui code.
> > Guis should be dumb.
I agree and would add that GUI code should only have GUI-related logic, but no business logic. Many applications require presentation logic. This comes in all sorts of formats such as logic in XSLT programs, scripplets in JSP pages, etc. The main thing is to cleanly separate business logic from presentation logic. As I mentioned, but it was deleted, was the Business Delegate should be used to decouple the two top tiers, e.g. Presentation and Business.
> >Along the lines of what
> > GhostRadio was saying, a really good design would be
> > usable in a web based app and in a swing based one.
> That's what I was hoping for. The data model
> shouldn't know or care what type of presentation
> layer is present, if any. The presentation layer
> shouldn't know or care where the data is coming
> from.
Yup, and to further add, the data model should no have any dependencies on the business logic/tier of the application. In the Java EE model, the three tiers are Presentation, Business, Integration. It is unidirectional. The tiers go below to get services/execute business logic and provide data to the tier above it.
> Yup, and to further add, the data model should no
> have any dependencies on the business logic/tier of
> the application. In the Java EE model, the three
> tiers are Presentation, Business, Integration. It is
> unidirectional. The tiers go below to get
> services/execute business logic and provide data to
> the tier above it.
To add to this, if you have the GoF book handy, have a look at the Builder pattern. It's not the most common pattern and may take some time to get your head around but it's really a sound way to design the abstraction between the gui and the data/business logic, especially if you plan to have more than one type of view. An example of this pattern in use that you might know is SAX.
> consider spring or other 'lightweight' frameworks alsoI'm sorry for posting an unrelated comment, but Spring is not 'lightweight'
In his defense, dubwai put the word lightweight in quotes to point out that he was using the term loosely.I've never used Spring, but it does sound like it is lighter weight than a Java EE app server like WebLogic or WebSphere. I'm sure that discussion could start a huge thread.
> Here's my question: Is this the type of app that
> lends itself to a Java EE design?
Nothing in the description suggests to me that a J2EE container is appropriate for this design.
Or for that matter why even a client server architecture is needed.
Is there some other detail that suggests this?
In my app, we have multiple clients that need to get to the same data from work, home, travel, etc. I could either allow direct JDBC connections to the DB server, or I could put some beans in front of the server to serve up entities. Since sys admins probably don't want to leave the MySQL ports open to the world, the Java app server approach seems more likely to be allowed.
So, I definitely need a client server approach. Whether or not I need a Java EE solution is still up for debate.
> In my app, we have multiple clients that need to get
> to the same data from work, home, travel, etc. I
> could either allow direct JDBC connections to the DB
> server, or I could put some beans in front of the
> server to serve up entities. Since sys admins
> probably don't want to leave the MySQL ports open to
> the world, the Java app server approach seems more
> likely to be allowed.
>
> So, I definitely need a client server approach.
> Whether or not I need a Java EE solution is still up
> for debate.
Still debatable.
While traveling there is no need to access the data unless an internet connection is present correct? And no preference to do it that way either?
And the travel and data needs coincide? Thus is someone is traveling to a location where the internet is accessed via a 21k baud modem the data needs of the application/use are so low that actually using the internet at that speed will not be a problem?
What is the timeliness of the data? How often, excluding the travel updates, does the data for a traveling user need to be updated?
What is the concurrent usage patterns of the data? How often will one traveling user need to access data that someone else has updated? Or vice-a-versa.
> While traveling there is no need to access the data
> unless an internet connection is present correct?
> And no preference to do it that way either?
You're right that remote data access is only possible when an internet connection is available, but this is rather common in our situation. Our users have need for constant access to the DB.
> And the travel and data needs coincide? Thus is
> someone is traveling to a location where the internet
> is accessed via a 21k baud modem the data needs of
> the application/use are so low that actually using
> the internet at that speed will not be a problem?
Much of the time, our traveling users have broadband connections of some sort.
>
> What is the timeliness of the data? How often,
> excluding the travel updates, does the data for a
> traveling user need to be updated?
>
> What is the concurrent usage patterns of the data?
> How often will one traveling user need to access
> data that someone else has updated? Or vice-a-versa.
It's not extremely important that a traveling user needs to have the absolute latest, up-to-date data. They could work off of a local cache or something like that.
However, the simple requirement that 2 different users in 2 different buildings have simultaneous access to the up-to-date data is certain. When one user adds new data, all the other users, enterprise wide (except maybe for 'roaming' users such as travelers) need the see the updates immediately.
I don't see any way to provide multiple users with simultaneous access to the same data without having some sort of client/server architecture.
> However, the simple requirement that 2 different
> users in 2 different buildings have simultaneous
> access to the up-to-date data is certain.
That is unusual.Most businesses never have that need. Sales reps, customer support, etc are very unlikely to deal with the same account. Accounting is usually the one with the broad spectrum need but their needs are seldom more than daily and almost always dealing with old data.
> When one
> user adds new data, all the other users, enterprise
> wide (except maybe for 'roaming' users such as
> travelers) need the see the updates immediately.
>
That again is unusual. Things like price changes seldom take effect immediately. Customers get really upset if a sales person tells them that the price is $1.00 and then when the order is submitted they are told that the price is now $1.50.
Even things like work flows are unlikely to need immediate availability because, presuming effective management, they won't be acted upon immediately anyways (because the people processing them have a full work queue.)
> I don't see any way to provide multiple users with
> simultaneous access to the same data without having
> some sort of client/server architecture.
Won't be the same data anyways.
Using client server the following examples demonstrate this.
Processing example
1. Client A downloads prices into the client app for updates.
2. Client B downloads the price for widget X into the client sales app.
3. Client A submits the update.
4. Client B submits order.
Now what do you expect to happen in step 4? Does it get rejected? Does it automatically use the old price? Automatically use the new price and tells the sales person (or doesn't tell them)?
What happens in the following scenario?
Prereq: There is only one widget left in inventory.
1. Client A downloads that there is one widget left. Tells customer.
2. Client B downloads that there is one widget left. Tells customer.
3. Client A submits order (so no widgets are left.)
4. Client B submits order - oops!
> Processing example
> 1. Client A downloads prices into the client app for
> updates.
> 2. Client B downloads the price for widget X into the
> client sales app.
> 3. Client A submits the update.
> 4. Client B submits order.
>
> Now what do you expect to happen in step 4? Does it
> get rejected? Does it automatically use the old
> price? Automatically use the new price and tells the
> sales person (or doesn't tell them)?
>
> What happens in the following scenario?
> Prereq: There is only one widget left in inventory.
> 1. Client A downloads that there is one widget left.
> Tells customer.
> 2. Client B downloads that there is one widget left.
> Tells customer.
> 3. Client A submits order (so no widgets are left.)
> 4. Client B submits order - oops!
I don't exactly run into these situations since my app has nothing to do with business. My app is much more like the card catalog for a library. The contents grow quite a bit, but rarely does an item get removed from the library property lists. Things get loaned out, but in general, they don't get removed from the property lists (unless damaged irreparably or lost).
The second example you gave is still valid:
1. Visitor A looks to see if "Title A" is in the library. It is.
2. Visitor B looks to see if "Title A" is in the library. It still is.
3. Visitor A chooses to reserve the book for checkout. No problem.
4. Visitor B chooses to reserve the book for checkout. It's unavailable.
I'm not sure exactly how we will solve this other than show an error screen for Visitor B saying that the book is no longer available (and when it might become available). I don't think this is all that uncommon. If I got Amazon and try to buy a book, but another customer buys the book seconds before I hit "Add to cart", the site will tell me that the book is on back order (which is equivalent to saying that it is currently unavailable).
If you're still implying that I could possibly design this system as a completely stand-alone app, not a client/server or enterprise app architecture, then I'm totally missing how these examples help to show that. Can you elaborate?
jschell, what other archtecture would you suggest for this other than client-server or 3-tier?
> jschell, what other archtecture would you suggest for
> this other than client-server or 3-tier?
So far the requirements suggest that it is possible that a client server could work. When I posed my first question it wasn't clear that that was mandated.
It isn't entirely clear that a client server will work since not all of the requirements are known. Although it would seem to be tending towards that with more information now available.
Certain scenarios could require that an off line model be used. And without other requirements with a J2EE solution that could end up requiring basically two implementations, one for the off line mode and one for the J2EE mode. If off line is more appropriate then it should be used.
Aside from that up until the internet requirement there wasn't anything to suggest that a direct to database model wouldn't work just as well and be less work (given as the OP has no previous J2EE experience.)
The only thing about the "direct to database" model that scares me is this: the local sys admin, as well as the admins at other sites, don't want the DB ports open to non-localhost connections. They would rather a local app (Java EE app server, etc) make connections locally (or at least on a small subnet behind a tight firewall) and those apps are accessed over the web somehow. This issue is what led me to look for a Java EE solution to my problem.
>
> I don't exactly run into these situations since my
> app has nothing to do with business. My app is much
> more like the card catalog for a library. The
> contents grow quite a bit, but rarely does an item
> get removed from the library property lists. Things
> get loaned out, but in general, they don't get
> removed from the property lists (unless damaged
> irreparably or lost).
>
> The second example you gave is still valid:
> 1. Visitor A looks to see if "Title A" is in the
> library. It is.
> 2. Visitor B looks to see if "Title A" is in the
> library. It still is.
> 3. Visitor A chooses to reserve the book for
> checkout. No problem.
> 4. Visitor B chooses to reserve the book for
> checkout. It's unavailable.
>
> I'm not sure exactly how we will solve this other
> than show an error screen for Visitor B saying that
> the book is no longer available (and when it might
> become available). I don't think this is all that
> uncommon.
It is common. But let your users drive your solution rather than letting the technology drive it.
> If I got Amazon and try to buy a book, but
> another customer buys the book seconds before I hit
> "Add to cart", the site will tell me that the book is
> on back order (which is equivalent to saying that it
> is currently unavailable).
>
It is more complicated than that. Amazon parteners can't return that info at all. They would have to tell you about that via email.
And amazon will not just say you can't have it. They will instead offer a back order option (which when ever I see it always includes an expected delivery date.)
> If you're still implying that I could possibly design
> this system as a completely stand-alone app, not a
> client/server or enterprise app architecture, then
> I'm totally missing how these examples help to show
> that. Can you elaborate?
Two standard solutions. There are mixed solutions depending on needs.
1. Off line. This involves keeping a copy of the database or something like the database on the client. When the client connects then the copies are sync'd. Note that if you have one single use case that requires this, then if you don't implement all of the solutions using this model then the application will be significantly more complicated. This sort of solution can use work requests rather than actual check outs. The request runs during the sync and has business rules appropriate for the request (like if an item is already checked out the putting it in a wait queue.)
2. Direct to database. Your internet need would nullify this possibility. Or at least it would for normal internet connectivity. If you are using a vpn and depending on actual functionality and usage patterns then this might be more of an option.
> I'm currently tasked with rewriting a legacy DB app
> in Java. The original was written in Delphi. It
> worked great for a number of years, but the powers
> that be have recently decided to redesign and rewrite
> it in Java. Basically I just have the same set of
> business requirements as the original did.
>
> Overall, the app is a desktop GUI application that
> helps track contents of a natural history museum
> collection. The collection contains a bunch of
> specimens (dead animals) collected all over the globe
> at various times over the last 200 years. Multiple
> users (1 - 10 uesrs) will have to have access to the
> data at the same time. I also have to provide a nice
> Swing GUI for it.
With AJAX, it's possible to have some pretty rich web clients these days. No reason to restrict yourself to Swing just because the legacy is desktop.
> Here's my question: Is this the type of app that
> lends itself to a Java EE design? I'm imagining
> using a Java EE app server that connects to the DB.
> The app server would provide DB access, producing
> entity beans,
Don't have to be entity beans. Can be DAOs and POJOs.
> as well as managing a number of
> session beans (EJBs) that implement the business
> logic
I see service interfaces and POJOs.
> (security, user management/session
> management).
Cross-cutting concerns.
> I would also have a Swing GUI that
> would connect to the beans remotely. This sounds
> like it would help me keep a good disconnect between
> the UI layer (Swing), the business logic (EJBs), and
> the data layer (entity beans accessed using the Java
> Persistance API). Does this sound reasonable? I'm
> a veteran Swing developer, but not a seasoned Java
> EE developer/designer.
Very reasonable, indeed.
> Also, if I use this architecture, I can imagine one
> issue that I might run into (I'm sure there are many
> others). I can imagine that I would want to retrieve
> the entity beans (lets say mypackage.MyPersonBean)
> through some call to an EJB, and then use the bean in
> some rendered Swing component. What happens when the
> Swing component needs to access the results of
> MyPersonBean.getAddresses() if the addresses are lazy
> loaded?
Chatty dialog with the database and slow performance, depending on the app server you plan to use and whether or not you use Remote or Local interfaces.
> As you can probably tell, I really have more than one
> design question here. Help/comments about any of
> this is greatly appreciated.
Think Spring. You can do this without EJBs.
http://www.springframework.org
They've got a rich client module that might help with Swing if you decide to go that way. I haven't used it myself, because I don't Swing.
%
> The only thing about the "direct to database" model
> that scares me is this: the local sys admin, as well
> as the admins at other sites, don't want the DB ports
> open to non-localhost connections. They would rather
> a local app (Java EE app server, etc) make
> connections locally (or at least on a small subnet
> behind a tight firewall) and those apps are accessed
> over the web somehow. This issue is what led me to
> look for a Java EE solution to my problem.
If it was me I wouldn't want the DB ports open to the internet either.
But as I said if you were using VPN then that wouldn't be the case. Not that I am suggesting that you should use VPN but rather if that is driven by some other requirement then use it.
Really so far nothing suggests that you shouldn't use a J2EE container. So far it would seem that a servlet container would be sufficient.
> If it was me I wouldn't want the DB ports open to the
> internet either.
>
> But as I said if you were using VPN then that
> wouldn't be the case. Not that I am suggesting that
> you should use VPN but rather if that is driven by
> some other requirement then use it.
>
> Really so far nothing suggests that you shouldn't use
> a J2EE container. So far it would seem that a
> servlet container would be sufficient.
I'll second what I believe jschell is saying here. If you don't know why you are using EJB, you probably don't need it. Go with the more simple design first and if it proves to be insufficient, start looking EJB and other more complicated frameworks. You can easily lose track of using these tools as a means to an end and have them beceome ends unto themselves. Make sure you have a problem in hand and figure out how the tool or technique solves it.
Thanks for all the replies, replies to replies, and replies to replies to replies. This discussion has all been good to here.
> I've never used Spring, but it does sound like it is
> lighter weight than a Java EE app server like
> WebLogic or WebSphere.
Spring is not a server, it's a framework. And you can opt to use pieces and parts so i suppose it CAN be lightweight. However, that general statement that "spring is lightweight" is laughable, but I got your point about using the term loosely.
> I'm sure that discussion
> could start a huge thread.
And indeed it has many times over and will in the future..