10 Replies Latest reply on Nov 3, 2007 2:33 PM by alessandrolt

    Entity withiout Injection --- How do construct a efficient D

    alessandrolt

      I know that can´t use @In with Entities objects. But, I need inject "Repositories" in entity class for "find" things of my Domain Model.

      The designs, for example like Domain Model (DDD), says that logic and data exist in same class (Fowler/Evans). If use development with JBoss Seam, how can I construct a efficient Entity without injection (D.I.)?


      -----------------------------
      []´s
      Alessandro Lazarotti

        • 1. Re: Entity withiout Injection --- How do construct a efficie
          alessandrolt

          The title of topic is:

          Entity withiout Injection --- How do construct a efficient Domain Model.

          • 2. Re: Entity withiout Injection --- How do construct a efficie

            You need to create appropriate mappings for your entities. If you have mapped object associations, the associations your entity requires will automagically be retrieved lazily (or when the entity itself is retrieved if eager fetching is desired). Read up on JPA and Hibernate for this.

            Once you have accomplished this, the only place you will need to inject a DAO or your EM is where the request for the entity occurs (likely in an SFSB). Seam also provides a Seam Managed Persistence Context (SMPC) which allows you to achieve lazy initialization across requests.

            Good luck.

            • 3. Re: Entity withiout Injection --- How do construct a efficie
              alessandrolt

              I´m work with JPA and associations. But a "Repository Pattern" isn´t a relationship, is much more.

              In my Entity Bean, I need execute complex query (by your attribute "Repository"). The implementation of the Repository class is child of EntityHome. I don´t know how instanciate or inject this Repository in the Entity.

              If not possible, how do work with "Domain Driven Design" in JBoss Seam?

              Thanks


              -------------------------
              Alessandro Lazarotti

              • 4. Re: Entity withiout Injection --- How do construct a efficie
                matt.drees

                It's not possible to inject components into an entity. However, you can look them up:

                Component.getInstance("repository")
                


                or
                Component.getInstance(Repository.class)
                



                • 5. Re: Entity withiout Injection --- How do construct a efficie

                  Yes, good point Matt. I suppose the only problem with looking up is you will have to test within the container (the essential problem with testing old-school EJBs). You could always use SeamTest for testing these calls within your DM, but TDD purists would probably argue with that. I certainly see alessandrolt's concern. There are some interesting discussions about this on the Spring forums and here:

                  http://debasishg.blogspot.com/2007/02/domain-driven-design-inject.html

                  I would be curious if there are there any plans for support of this approach within Seam?

                  • 6. Re: Entity withiout Injection --- How do construct a efficie
                    matt.drees

                    For my stuff, if I need to access Seam components in an entity, I usually do something like

                    Repository.instance();
                    


                    My static instance methods look something like this:
                    static instance() {
                     return InstanceManager.instance().getInstance(Repository.class);
                    }
                    


                    And then InstanceManager either looks it up from Seam, or if Seam isn't available (simple unit tests), keeps a pool of Singletons.

                    Still kinda kludgy, but it's practical.

                    • 7. Re: Entity withiout Injection --- How do construct a efficie

                      Very creative, I like it. I really am curious about Entity injection though. I could see other situations as well where other types of Service objects (not just a Repository) are required within an Entity to get the job done. Injection of the Service object instance would certainly be desirable to performing lookups.

                      • 8. Re: Entity withiout Injection --- How do construct a efficie
                        matt.drees

                        I think I agree. I imagine you could set up some kind of hibernate or entityManager listener to do injection. Has anyone tried that?

                        • 9. Re: Entity withiout Injection --- How do construct a efficie
                          pmuir

                          You should use programmatic lookup, creating an instance method is a neat way to do that.

                          • 10. Re: Entity withiout Injection --- How do construct a efficie
                            alessandrolt

                            Using aspect I kept the annotation @In in Entities, may inject any seam component.

                            The Aspect intercepting the criation of the Entity and search the annotation @In. After it inject by Component.getInstance("componentName").

                            Below that the code written in AspectJ:

                            Using aspect I kept the annotation @In in Entities, may inject any seam component.

                            The Aspect intercepting the criation of the Entity and search the annotation @In. After it inject by Component.getInstance("componentName").

                            Below that the code written in AspectJ:

                            public aspect InjectEntity{
                            
                             //intercept the package of Entities
                             pointcut inject() : initialization(public br.com.siq.pesquisa.entidade.*.new (..));
                            
                             after():inject(){
                             Object obj = thisJoinPoint.getThis();
                             String valueOfContextVariable = null;
                             Boolean createContextVariable=false;
                            
                             for(Field field:obj.getClass().getDeclaredFields()){
                             if(field.isAnnotationPresent(In.class)){
                            
                             In in = field.getAnnotation(In.class);
                            
                             if(in.value().equals("")){
                             valueOfContextVariable = field.getName();
                             }else{
                             valueOfContextVariable = in.value();
                             }
                            
                             if(in.create())
                             createContextVariable = true;
                            
                             field.setAccessible(true);
                            
                             try {
                             field.set(obj, Component.getInstance(valueOfContextVariable, createContextVariable));
                             } catch (IllegalStateException e) {
                             log.error("Don´t have context active");
                             }catch(Exception e){
                             log.error(e);
                             }
                             }
                             }
                             }
                            
                            }
                            
                            


                            The code of Entity now can be written with:

                            @Entity
                            public class User{
                            
                             @In
                             private UserRepository userRepository;
                            
                             //more code
                             (...)
                            
                            }
                            


                            ... the Entity user isn't necessarily a Seam component, but works ;)

                            -----------------------------
                            []´s
                            Alessandro Lazarotti