10 Replies Latest reply on Nov 28, 2005 6:58 PM by Thomas Orr

    Entities and Interfaces

    Thomas Orr Newbie

      It seems that the EJB3 Entities concept is limiting my attempts to decouple my application from entities.

      I have a package that defines the interfaces of my entites, com.me.entites. I have an interface in here called Session. This interface has no coupling to ejb3. I then create a package for the ejb3 implementation, com.me.entities.impl.ejb3. I have my ejb implementation in there, annotations and all.

      In my persistence XML I have only the implementation as required for management,

      <class>com.me.entities.impl.ejb3.Session</class>
      . However, this par fails to deploy.

      Could not determine type for: com.me.entities.Session, for columns:
      ...
      --- MBeans waiting for other MBeans ---
      ObjectName: jboss.j2ee:service=EJB3,module=entities.par
       State: FAILED
       Reason: org.hibernate.MappingException: Could not determine type for: com.me.entities.Session, for columns:
      ...
      [org.hibernate.mapping.Column(session)]
      


      I get the feeling that even the interface needs to be coupled to ejb3. This is bad. I've been a proponent of ejb3, in general. However, this is a huge shortcoming - a show stopper for sure. I hope this is simply a bug.

      One unacceptable solution is to use DTOs as my decoupled interface. Sorry, this is just getting too complicated. EJB3 is supposed to be simple. I understand the value of DTOs, but in this case it is too much overhead for this simple case.

      So, am I doing something wrong, is this a bug, or is this part of the system?

        • 1. Re: Entities and Interfaces
          Kabir Khan Master

          By specifying your interface in the

          <class>
          of persistence you are telling the deployer that this is an entity bean, which is not the case. Get rid of that.

          • 2. Re: Entities and Interfaces
            Thomas Orr Newbie

            That is the implementation.

            • 3. Re: Entities and Interfaces
              Emmanuel Bernard Master

              When you link your entities.Session use targetEntity to give the proper mapped implementation

              ie
              @ManyToOne(targetEntity=entities.impl.ejb3.Session.class)
              Session getSerssion()

              However I find the idea of using an interface incredibly bad. It slows you developement by having 2 artefacts to maintain and no concrete benefit.

              • 4. Re: Entities and Interfaces
                Thomas Orr Newbie

                Target entity seems to have solved it. Thanks. It was my bad anyhow since this particular entity should have been backed by an SP and not entity managed relations.


                However I find the idea of using an interface incredibly bad. It slows you developement by having 2 artefacts to maintain and no concrete benefit.


                I guess that's valid. However, I most often see development of highly configurable, extendable solutions using the "code to interfaces" approach. It is important to follow this pattern (for me) so that I can make use of factories, as well as be able to hot swap my persistence strategy. EJB3 has not yet won my company over. There are certain features that do not exist, and ones that can be improved...but hey, I didn't have any say on the spec.

                I don't mean to push other technologies in this forum, but IBatis has a couple of beneficial features that may end up making it the persistence choice at my company. Entites seem especially suited to those willing to give up database control to their domain model. We won't go this route, so our persistence strategy has to integrate very well with SPs. Entites do a fine job. IBatis does it better. So, I must be prepared to change this at a moments notice with as little impact as possible. Since I use the entities as DTOs, their implementation must be swappable so that clients are not indirectly tied to EJB3. Coding to interfaces makes this as painless as possible.

                So, you may find the idea of using an interface incredibly bad. I hope that all your projects are of the sort that you do not have to not incur the worry of change management. If they do, however, you may find yourself using interfaces to define the contracts rather than the implementations. I have explained the concrete benefit. 2 files are a small price to pay for the flexibility. It's all about balancing pros and cons, no?

                • 5. Re: Entities and Interfaces
                  Thomas Orr Newbie

                  ...I've been looking at the entity-mapping.xml schema in the spec. If this worked, it would make the need for interfaces a non-issue. There would be no-ejb specific annotations in my implementation. However, as of yet it doesn't seem to be fully baked. I've introduced it to my codebase, but it is just ignored.

                  • 6. Re: Entities and Interfaces
                    Bill Burke Master

                    we won't support this until Q1 next year. Use Hibernate mapping files. They will work

                    • 7. Re: Entities and Interfaces
                      Emmanuel Bernard Master

                       

                      "redijedi" wrote:
                      I guess that's valid. However, I most often see development of highly configurable, extendable solutions using the "code to interfaces" approach. It is important to follow this pattern (for me) so that I can make use of factories, as well as be able to hot swap my persistence strategy.

                      Of course for your *Services*, but does not make sense for you POJOs. What's the point of abstracting pojos that are just not technology related?

                      I don't mean to push other technologies in this forum, but IBatis has a couple of beneficial features that may end up making it the persistence choice at my company.

                      IBatis has no features benefits over Hibernate

                      Entites seem especially suited to those willing to give up database control to their domain model.

                      ??? What does that mean. Entities are just object reprensentation of your relational model.

                      We won't go this route, so our persistence strategy has to integrate very well with SPs. Entites do a fine job. IBatis does it better.

                      SP integrate well with Hibernate

                      So, you may find the idea of using an interface incredibly bad. I hope that all your projects are of the sort that you do not have to not incur the worry of change management. If they do, however, you may find yourself using interfaces to define the contracts rather than the implementations. I have explained the concrete benefit. 2 files are a small price to pay for the flexibility. It's all about balancing pros and cons, no?

                      I do projects with business and technologies changes. I use Interfaces when useful (services), I do not use interfaces for the pleasure of abstracting a *single* implementation aka your domain object which is technology independent.

                      • 8. Re: Entities and Interfaces
                        Thomas Orr Newbie

                         

                        Of course for your *Services*, but does not make sense for you POJOs. What's the point of abstracting pojos that are just not technology related?


                        How are they not technology related? If I use EJB3 Entities as my implementations for the POJOs, then they are tied to EJB3.

                        IBatis has no features benefits over Hibernate


                        There is at least this one: using IBatis, I can pass an entire pojo to the SQLMapClient (EntityManager analog) and dereference its properties in the proc/native sql call like so:

                        <update id="updatePerson" parameterClass="examples.domain.Person">
                        UPDATE PERSON
                        SET PER_FIRST_NAME = #firstName#,
                        PER_LAST_NAME = #lastName#, PER_BIRTH_DATE = #birthDate#,
                        PER_WEIGHT_KG = #weightInKilograms#,
                        PER_HEIGHT_M = #heightInMeters#
                        WHERE PER_ID = #id#
                        </update>
                        


                        The texts between the hash marks represent properties of the Person object. This is advantageous because I do not have to call em.setParameter()... for however many params I plan I setting. This simple feature is very beneficial when using SPs and something that Hibernate does not do. Also, since I define my pojos by interface, I can pass in any object that implements the interface. Yet another reason why not using interfaces with the POJOs is short-sighted.

                        ??? What does that mean. Entities are just object reprensentation of your relational model.


                        Exactly, they are object representations of your relational model. Therefore, if you use stored procs, you are not using the various features that are built out in ejb/hibernate to support the relational model (many-to-one, etc...). These features make up the bulk of the EJB3 Entity API. This is why they are especially suited to those who wish to control CRUD access to the underlying database using these objects.

                        SP integrate well with Hibernate


                        Yes, they integrate well. Not fantastically well, but well. See above for why there are better solutions in this particular case.

                        I do projects with business and technologies changes. I use Interfaces when useful (services), I do not use interfaces for the pleasure of abstracting a *single* implementation aka your domain object which is technology independent.


                        Good for you. Still, I do not think you understand what technology independent means. If an entity is a pojo that requires EJB3 it is not technology independent. Entites require EJB3 on the classpath because they use annotations. If you doubt this, try pulling your ejb3 libs out of your classpath and see if they will compile. I know that's a little java 101, but I fail to see why you do not understand. Furthermore, if services depend on this implementation, they too are indirectly tied to EJB3. Since you refuse to use interfaces for your POJOs, then your services will depend on the EJB3 implementations - there's no two ways around that.

                        I like EJB3, so I do not mind tying my implementations to it. However, I do need to reserve a low impact way out if it does not pan out for any reason. That's just being pragmatic. I can do so using plain old java patterns that have been built in since day one. If you don't like it, tough.


                        • 9. Re: Entities and Interfaces
                          Emmanuel Bernard Master

                           

                          "redijedi" wrote:
                          How are they not technology related? If I use EJB3 Entities as my implementations for the POJOs, then they are tied to EJB3.

                          no specific abstract class, no specific interface to implements.

                          There is at least this one: using IBatis, I can pass an entire pojo to the SQLMapClient (EntityManager analog) and dereference its properties in the proc/native sql call like so:

                          <update id="updatePerson" parameterClass="examples.domain.Person">
                          UPDATE PERSON
                          SET PER_FIRST_NAME = #firstName#,
                          PER_LAST_NAME = #lastName#, PER_BIRTH_DATE = #birthDate#,
                          PER_WEIGHT_KG = #weightInKilograms#,
                          PER_HEIGHT_M = #heightInMeters#
                          WHERE PER_ID = #id#
                          </update>
                          


                          The texts between the hash marks represent properties of the Person object. This is advantageous because I do not have to call em.setParameter()... for however many params I plan I setting. This simple feature is very beneficial when using SPs and something that Hibernate does not do.


                          You can override the update statement of any entity in hibernate even using sp, check the ref doc.

                          Exactly, they are object representations of your relational model. Therefore, if you use stored procs, you are not using the various features that are built out in ejb/hibernate to support the relational model (many-to-one, etc...). These features make up the bulk of the EJB3 Entity API. This is why they are especially suited to those who wish to control CRUD access to the underlying database using these objects.

                          You domain object reprensent your relational model. The relational model goes beyond the tables in your schema. You can map views and sp on entities in Hibernate.

                          Good for you. Still, I do not think you understand what technology independent means. If an entity is a pojo that requires EJB3 it is not technology independent. Entites require EJB3 on the classpath because they use annotations.

                          No, they do not requires the ejb3 api on the classpath at runtime.
                          Remove java.lang.Object from your CP, your domain will not compile ;-)
                          To be more serious, if you care about annotations, just use hbm.xml files and latter next year the portable EJB3 DD.

                          I like EJB3, so I do not mind tying my implementations to it. However, I do need to reserve a low impact way out if it does not pan out for any reason. That's just being pragmatic. I can do so using plain old java patterns that have been built in since day one. If you don't like it, tough.

                          Think in overhead on your dev time / arch complexity:
                          - your solution: 2 classes each time + factories etc etc + 1 class per entity for the new implementation.
                          - mine: 1 class + if you really care, a script to remove all annotations from you domain model when you want to switch to a new implementation
                          I definitly choose the last one, my manager too.


                          • 10. Re: Entities and Interfaces
                            Thomas Orr Newbie

                             

                            no specific abstract class, no specific interface to implements.


                            This is true, but the SqlMapping has to map onto a specific implementation. So, even if you pull properties from an arbitrary object and use the setParameter method on your Query, the Query will still map the results to a known implementation. This is unescapable, and not the problem anyhow.

                            You can override the update statement of any entity in hibernate even using sp, check the ref doc.


                            Maybe the "update" was a bad choice. The point is that in any native sql call, I can dereference properties of the object I pass in inside of the native sql call definition. In the previous example, #lastName# will pass in the value of PersonInstance.getLastName() as opposed to me calling setParameter for each property that I want passed into the SQL call. This is not a deal breaker for me, but it is more convenient.

                            You domain object reprensent your relational model. The relational model goes beyond the tables in your schema. You can map views and sp on entities in Hibernate.


                            Right, but I do not wish to do so. The features are there for those that do. Most of the features in EJB3 Entities are there for those that use this technique. With SPs, how am I supposed to indicate that want to call a named native query on select from bean 1 when I select from bean 2 that has a relation to bean1? As far as I see it, you cannot. Nor would I want to (just my preference). The entity manager is responsible for calling named queries. Therefore, I would need two call to the EM (this is how I do it now, and that's fine). The relationship mappings for Entites do not support an automatic cascade of sp calls through the entity graph, as I understand it. The possibility exists that I do not fully understand how this works. However, from what I have read and my own experiments, I do not see that this can be done. If it cannot, that's fine too. I prefer managing the calls opposed to setting up fetching relationships.

                            No, they do not requires the ejb3 api on the classpath at runtime.
                            Remove java.lang.Object from your CP, your domain will not compile ;-)
                            To be more serious, if you care about annotations, just use hbm.xml files and latter next year the portable EJB3 DD.


                            This is a viable alternative as I previously discussed.

                            Think in overhead on your dev time / arch complexity:
                            - your solution: 2 classes each time + factories etc etc + 1 class per entity for the new implementation.
                            - mine: 1 class + if you really care, a script to remove all annotations from you domain model when you want to switch to a new implementation
                            I definitly choose the last one, my manager too.


                            I do not mind multiple files so much. Any decent IDE can make this a simple task. I believe that you are exaggerating the difficulty in maintaining these. Eclipse: Refactor -> Extract Interface, then for subsequent updates you can use Override/Implement Methods to "resynch". If you are using command line tools, maybe you're in a different boat. I doubt that the majority of Enterprise developers are.

                            The need to remain loosely couple is but one benefit of using interfaces. Yet, maybe I'm the special case. I have multiple business units, each with their own idea of what a User is. By defining an interface that they can adhere to I ensure that they can all be a client to my service while allowing them the freedom to express the User as it needs to be defined in their context. Whether this client passes me an ejb or some other implementation, my EJB3 service will know exactly what to do with it and my service will also pass back a technology neutral object that is only known by its interface. Nice and clean.

                            Clearly, we have different viewpoints. I think we have to chalk this one up to the fact that not every problem can be solved (or should be) by the same solution. I have determined that for my purposes I am more comfortable with the interface abstraction. We can both see that you would not do so. I do not think that your approach is bad, but it is not as good as mine for my situation. My solution may not be right for your situation. Such is life.