The Source for Java Technology Collaboration
User: Password:



Rima Patel Sriganesh

Rima Patel Sriganesh's Blog

What'd you like to hear in JPA Best Practices session in JavaOne?

Posted by rpatel on February 26, 2007 at 09:33 AM | Comments (13)

As some of you might know, the JavaOne 2007 proposal notifications went out last week. My proposal titled "Java Persistence API: Best Practices and Tips" has been accepted. In thinking about the contents for this session, I realized that in addition to the best practices about regular stuff such as flush mode, caching, etc., it would be nice if I can cover some of the things based on the community's suggestions. Hence, this blog entry.

So, if you have worked with JPA and have some insights to offer from your experience, please chime in by providing the following details:

1) The implementation of JPA you are using

2) Describe how you are using JPA

3) Describe any problem that you are facing with JPA usage

4) Describe - if you want to and can - how JPA could have solved this problem

Remember the following while submitting your opinion in the comments
section:

1) Please try to be constructive.

2) Please articulate the problem you're facing while using JPA -
architectural flaws, API flaws, anything - even though you might not have a solution. This helps because I am planning to feed back all the comments on this blog entry to the Sun engineer(s) working on JPA. So your effort will not be in vain.

Thanks!


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Hello.
    I am using JPA under netbeans with inter module persistence, and it is going to be hell. I even very strongly consider going back to make persistence by hand, just because of the inadequate PU class definition mechanism, regarding SE platform.
    Feel free to contact me if you want more information. There would be enough to clutter that space.

    Posted by: pepe on February 27, 2007 at 06:55 AM

  • Pepe,

    Interesting. Can you send an email to me at rima dot patel at sun dot com describing your problem?

    Thanks,
    Rima.

    Posted by: rpatel on February 27, 2007 at 10:00 AM

  • What I'm doing with JPA is I have one project with all the EJB 3.0 annotated entities and a persistence.xml in it. I can then hand the jar that project creates and tada! They have persistence, whether they are stand alone or in a container somewhere.

    While it is (in theory) documented, there are significant differences between running JPA standalone and in a container, and it seems the fastest way to figure something out is to try it - if it is broken then try to fix it... if it can't be fixed conclude that it fits into the basket of things that don't work standalone.

    the toString method Netbeans makes for you when it builds an entity is wrong, it should read:
    return this.getClass().getName() + "[id=" + id + "]";
    so that if you refactor it you don't think the persistence unit is somehow picking up the old class... (the current class name is hard coded into the string it gives you)

    Some of the relationship annotations netbeans builds for you are not so good. I took to pulling them out and going with the defaults (which are suprisingly good - except the occassional @ManyToOne which needed to have cascade set on it (some do, some don't... it is not really clear to me what the implications are for the different cascade types, this is an area which could do with a bit of addressing)).

    In not entirely unrelated news, dropping strangely named foreign keys from tables is tedious and annoying. In netbeans if you right click on the foreign key it would be nice to add a delete option :D And/or if you try to delete a table and it won't let you because of foreign keys a "nuke from orbit with extreme prejudice" option would be even better :D

    I can while using Spring and stand alone JPA inject an EntityManager using the @PersistenceContext annotation, but it was a pain in the posterior to figure out. Also using Spring I can get @Transactional on my service layer methods so I don't need to manually get an EntityTransaction from the EntityManager... being able to do similar in JPA standalone would be nice I think. :D

    Some of the Netbeans examples are broken. For instance while JAX-WS support in Netbeans 'rocks my lame world (tm)', some of the examples (eg Webservice which is also a Stateless Session Bean) don't work. (Or maybe they only work in Glassfish if you twiddle its twiddly bits properly). From reading about when different annotations are processed and by whom/what, I'm not even clear if this is possible in a full on honest to God 110% Java EE 5 container because of conflicts between annotations. (Eg when deployed the annotation processor which processes the @Webservice annotation pitches a fit when it hits the session bean annotations).

    Which led to me throwing out Session Beans entirely, as they are now clearly much much more trouble than they are worth... ? (note question mark: that might be something you could address, eg how to make all these things play nice)

    If I want to share my code with peers outside of my current company, going back through the persistence.xml to xxxx out the user name, password and ip address of the database is kind of annoying, is there a way to do this, or keep them separate _without_ getting JNDI involved?

    Not entirely unrelated - JNDI sucks. :D It is horrible, I loathe and despise it with a passion. (you may by now have deduced that I am not entirely objective on this subject). Is there a way to spit out the JNDI settings for one developer so that new developers can be added to a project without having to spend weeks trying to figure out all the magic twiddly bits you did in JNDI over the course of the project? Some kind of JNDI browser at least? Some way to easily replicate the bits you need when you deploy to production?

    Posted by: rickcarson on February 27, 2007 at 03:40 PM

  • I am using EBJ3 on JBoss. It is common that I have shared components deployed in their own ear that are accessed via a remote session call from another app.

    Previously, when this involved retrieval of information from the database, there was a lot of DTO code to mess with. It's great that I can now just pass back a detached entity, but there seems to be a small piece missing to make this really work smoothly. I can annotate the entity to make some portions lazy loading and others eager loading, but once it is detached it is too late to fetch the lazy fields. This leads to session beans that have to call a bunch of getters before returning an entity to make sure all the fields are loaded.

    It would be nice to have a method on EntityManager like "void eagerLoad(Object entity, int depth)". The depth would be used to specify the number of relationship links to follow, with 0 meaning that just non-relationship lazy fields are loaded, and some special constant (-1) to indicate that the entire tree of relationships should be loaded.

    Posted by: sarnoth on February 27, 2007 at 04:10 PM

  • Another thing to look out for with JPA is that most of the examples are for (certain builds of) Glassfish and TopLink, whereas everybody not using Oracle databases is probably going to be using Hibernate, so showing how to get Hibernate up and tuned right would probably be a good thing (particularly things like the Hibernate TreeCache, which people may not even be aware of for their distributed caching needs).

    On the other hand, Hibernate also breaks the spec. I found that if I tried to persist an object which already exists, it was fine with that, whereas what it should have done is spat the dummy and thrown an 'EntityAlreadyExistsYouFool' exception. So people may find it useful for you to talk about these differences between the reference implementation and the real world.

    One of the great things about JPA is that I despise Hibernate mapping files with a passion, and by slapping JPA on the top I never ever need to worry about them. So when I'm working on a project and they insist that we use Hibernate I can truthfully tell them that we are using Hibernate. :D Also, I can quickly swap out Hibernate and replace it with something else should I so desire. JPA may only be a thin facade over the top... but that is a good thing.

    Probably everyone will have a horror story about past projects when working with dates and times (as each database handles them differently) and so talking about that (as in - what annotations and JPA do for you to make your life easier when dealing with dates) might be of interest.

    When dealing with JPA probably the biggest conceptual hurdle people have to leap is Entity Detachment, when entities get detached, when and how to reattach them and so forth. I read the spec and thought I had a good handle on it, but half the things that I thought I had to do turned out (in practise) to be unnecessary. Maybe walk people through what happens when you call em.merge(o) for instance. And some changes to an object will get persisted transparently, whereas others won't. When to do a persists (when you would have done an SQL insert) and when to do a merge (when you would have done an SQL update).

    the hibernate fan(atics) in particular seem to have great difficulty with persist vs merge.... I think this is because they are used to just calling em.save(o), and having the framework figure out for them whether it was a new one or an old one (hence the failure to throw the appropriate exception which I mention above)

    Posted by: rickcarson on February 27, 2007 at 05:07 PM

  • +1 for eager loading vs lazy loading :D

    Posted by: rickcarson on February 27, 2007 at 05:09 PM

  • Sometimes (frequently) during development Tomcat won't shut down properly because the persistence layer won't shut down properly. This is... worrying... for something that is supposed to be able to be deployed into production...

    *Right now* for instance, I am about to close Netbeans because of this. I expect to do this about 2-3 other times today. A reboot of the machine is not entirely out of the question. In case no one has noticed, it is 2007.... I should not have to reboot the machine. (NB: running on Windows with a pittance of RAM, so not _entirely_ Netbeans/EE5s fault that I have to do this, as my work machine is so old and decrepit (and windows...))

    Posted by: rickcarson on February 27, 2007 at 05:16 PM

  • Although their pain and suffering is entirely self inflicted and hence I have 0 sympathy for them... ;-) perhaps the Eclipse developers would like you to say some stuff relevant to them?

    Posted by: rickcarson on February 27, 2007 at 05:18 PM

  • about eager loading vs lazy loading: on a previous project we were using hibernate with mostly lazy loading, but we needed the object data (including child objects) displayed in the Web UI to be configurable. So we ended up doing a lot of eager loading of complex relationships (otherwise a get on child relations of the detached object caused exceptions). This caused bad performance so we used the "Open Session in View" pattern ( JPA Transaction view) where a servlet filter opens and closes the transaction, which did improve performance because only the data that was accessed was loaded. In the Pro EJB 3 book, it discusses this option plus Entity Mgr per request, and projection queries
    Posted by caroljmcdonald at March 15, 2007 06:35 AM

    Posted by: caroljmcdonald on March 15, 2007 at 06:35 AM

  • RickCarson,


    This is in response to your very first post on this blog.

    What I'm doing with JPA is I have one project with all the EJB 3.0
    annotated entities and a persistence.xml in it. I can then hand the jar that
    project creates and tada! They have persistence, whether they are stand
    alone or in a container somewhere.

    While it is (in theory) documented, there are significant differences
    between running JPA standalone and in a container, and it seems the
    fastest way to figure something out is to try it - if it is broken then try to fix
    it... if it can't be fixed conclude that it fits into the basket of things that
    don't work standalone.


    Rima - Yes, I agree that the way we use persistence unit within and without a container vary in many respects. And it is a good idea to put some tips on this in my presentation.


    the toString method Netbeans makes for you when it builds an entity is
    wrong, it should read:
    return this.getClass().getName() + "[id=" + id + "]";
    so that if you refactor it you don't think the persistence unit is somehow
    picking up the old class... (the current class name is hard coded into the
    string it gives you)

    Some of the relationship annotations netbeans builds for you are not so
    good. I took to pulling them out and going with the defaults (which are
    suprisingly good - except the occassional @ManyToOne which needed to
    have cascade set on it (some do, some don't... it is not really clear to me
    what the implications are for the different cascade types, this is an area
    which could do with a bit of addressing)).

    In not entirely unrelated news, dropping strangely named foreign keys
    from tables is tedious and annoying. In netbeans if you right click on the
    foreign key it would be nice to add a delete option :D And/or if you try to
    delete a table and it won't let you because of foreign keys a "nuke from
    orbit with extreme prejudice" option would be even better :D


    Rima - I believe that this relates more to how NetBeans does things than JPA's design fallacies. So I do not think that this feedback needs to be addressed in the best practices session. But certainly, NetBeans team should look at this feedback and try to generate intuitive code.


    I can while using Spring and stand alone JPA inject an EntityManager
    using the @PersistenceContext annotation, but it was a pain in the
    posterior to figure out. Also using Spring I can get @Transactional on my
    service layer methods so I don't need to manually get an
    EntityTransaction from the EntityManager... being able to do similar in
    JPA standalone would be nice I think. :D


    Rima - Absolutely agreed! It would be nice to be able to do injection in standalone JPA. Don't think that there is a best practice to work around this. The only solution to here is to actually write a light-weight container akin to Spring that services such requests from the developer.


    Some of the Netbeans examples are broken. For instance while JAX-WS
    support in Netbeans 'rocks my lame world (tm)', some of the examples (eg
    Webservice which is also a Stateless Session Bean) don't work. (Or
    maybe they only work in Glassfish if you twiddle its twiddly bits properly).
    From reading about when different annotations are processed and by
    whom/what, I'm not even clear if this is possible in a full on honest to God
    110% Java EE 5 container because of conflicts between annotations. (Eg
    when deployed the annotation processor which processes the
    @Webservice annotation pitches a fit when it hits the session bean
    annotations).

    Which led to me throwing out Session Beans entirely, as they are now
    clearly much much more trouble than they are worth... ? (note question
    mark: that might be something you could address, eg how to make all
    these things play nice)


    Rima - Again this is NetBeans centric feedback, and I will defer it to the NetBeans engineering to focus on it. Btw, have you tried posting this feedback to the NetBeans forum?


    If I want to share my code with peers outside of my current company,
    going back through the persistence.xml to xxxx out the user name,
    password and ip address of the database is kind of annoying, is there a
    way to do this, or keep them separate _without_ getting JNDI involved?


    Rima - Yes, you will either have to modify persistence.xml to remove information about user name, password, and other database specific information, or be prepared to use JNDI and pass this configuration information while looking up the persistence context in the JNDI. There is no other way, as far as I can tell, to escape Persistence.xml or JNDI.


    Not entirely unrelated - JNDI sucks. :D It is horrible, I loathe and despise it
    with a passion. (you may by now have deduced that I am not entirely
    objective on this subject). Is there a way to spit out the JNDI settings for
    one developer so that new developers can be added to a project without
    having to spend weeks trying to figure out all the magic twiddly bits you
    did in JNDI over the course of the project? Some kind of JNDI browser at
    least? Some way to easily replicate the bits you need when you deploy to
    production?


    Rima - JNDI is a necessary evil. I just wish the interfaces could have been easier. As for the JNDI Browser, Glassfish management console comes bundled with that functionality (Application Server -> General -> JNDI Browsing).

    Posted by: rpatel on March 19, 2007 at 03:26 PM

  • Is there any kind of seminar for JavaOne2007?I just completed JavaScript course and I would like to learn anything new from Java? I'm going on an interview in a few days, and they want an employee with JavaOne2007 knowledge and experience. Can I present them my JavaScript diploma and maybe go on a course for JavaOne2007. I don't konw much about it, but this job is very god and I would like to get it.
    Any suggestion is welcome...
    thanks in advance...if you want to contact me, you can do it here or leave a post on my web...
    again,
    I say thanks, and sorry if I asked in a wrong place...

    Posted by: lmanser on May 11, 2007 at 02:44 PM

  • All,


    Thanks a lot for providing your suggestions for this session. The session was a full house both times, and we hope that the attendees had a chance to learn from this session. If you attended this session at JavaOne, and have any suggestions, ideas, or feedback to provide, please do so as a comment on this blog entry. If you are looking for the slides, they would be made available here in a few weeks.


    LManser,


    The JavaOne 2007 presentation materials will be posted here in a few weeks. As I understand, the podcasts of most of these sessions will be available as well.


    Thank you,
    Rima.

    Posted by: rpatel on May 18, 2007 at 09:17 AM

  • Thanks Ms Sriganesh for the wonderful blog.

    Posted by: earnmycash on July 18, 2007 at 06:05 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds