Re: Tapestry Hibernate Session usage
On Tue, May 14, 2013 at 12:05 AM, Boris Horvat horvat.z.bo...@gmail.comwrote: Hi Dmitry Please ignore the naming as I haven't really user he real names here as this is just an example (the project also has nothing to do with Students but it is easier for the explanations :) ). In all fairness though I do prefer to append DAOService in front as it allows me to search for the class more easily (If my page, service and domain class all start with Student it is annoying to find anything) The @CommitAfter it is my manager that has this class not the DAO's so I guess why use the same approach As for the constructor and @Inject annotation I know that I can use it but in that way I restrain my self to Tapestry (or Spring), which is not the case if I use constructor. I am aware of the God anti pattern and while there is fine line between that and my code I dont think I have crossed it as I have more then one manager. They represent an area of business logic and basically they are place where transaction annotation is put. Still it is something to keep in mind I agree. I think now I understand a bit more about the Session object in Tapestry. So yes if it is shard across all of my DAO object that would be what the behavior what I need. Do you know any place where I can read a bit about it? I am interested it as from what I can see in my code constructor is only called once (you also confirmed this) so I was wondering how does it switch the Session object each time? You mention it is a proxy so I guess that is how it replaces it, right? You can read about proxies here: http://tapestry.apache.org/defining-tapestry-ioc-services.html http://tapestry.apache.org/defining-tapestry-ioc-services.html#DefiningTapestryIOCServices-DefiningServiceScope Thanks for the reply, Cheers, Boris On Mon, May 13, 2013 at 10:09 AM, Dmitry Gusev dmitry.gu...@gmail.com wrote: On Mon, May 13, 2013 at 2:59 AM, Boris Horvat horvat.z.bo...@gmail.com wrote: Hi all, Hi! I have a question about what should be the best way to use hibernate session in tapestry. My environment consists of 2 layers (relevant to this). The first one would be a group of classes that represent an access point to a table. For example if I have a table student then I will have a class DAOHibernateStudent. This class receives Session object in its constructor. Doing it this way I can separate all of the queries that are available for that table into its own class. Thats strange naming, I would name the interface as StudentDAO, and implementation as just StudentDAOImpl. Note that you can also @Inject session to your DAO, you don't have to pass it through the constructor. Btw, in my projects I never put @CommitAfter annotations in this layer. In this case I can do more than one DAO-method-call in a single transaction. The second layer is a class called Manager that implements business logic. This layer has fields that represent different DAOHibernate* classes. They are all passed down using constructor. This way I can keep my business logic in a special class which will communicate with different table using different DAOHibernate* objects Again, you don't have to pass DAO instances via constructor, use @Inject. Having one big Manager class looks like God Object anti-pattern to me -- http://en.wikipedia.org/wiki/God_object I usually have one Manager class per table, so in it would be named StudentManager in your case. Its okay having multiple different DAO instances to be injected in this ConcreteManager class also, as well as another manager classes if you wish. Usually I put most of @CommitAfter annotations on this layer, some of them goes to page classes event handlers directly. Depends on use-case. I use @Inject annotation to inject manager into a page Lets imagine that I want to create a new Student. So my code would call a Manager's method createStudent(some data) which would then use a few of the DAO classes to do all sorts of stuff (e.g. create a student, register subjects for him, assign him a mentor, add him to a student group, send notification email and so on...). The problem that I see here is that since all of those DAO classes are independent I need to use few Session objects as each one will receive its own session object. So here are my questions. As far as I know in tapestry there is only one instance of Session object per request (at least by default) -- its a per-thread proxy. And this Session instance is shared across all your DAO/Manager instances. 1. Will every time when someone loads/refreshes/opens the page a new Manager class be created which will in return create a new DAOHibernate* objects and each one will receive a new Session object? There are only two scopes for tapestry services now:
Re: Tapestry Hibernate Session usage
Questions about the 'magic' hibernate session proxy seem to crop up a bit so I've raised a Jira to improve the docs. https://issues.apache.org/jira/browse/TAP5-2115
Re: Tapestry Hibernate Session usage
Well thanks for help this makes my understating of the tapestry hibernate a lot better :) Cheers On Tue, May 14, 2013 at 4:38 PM, Lance Java lance.j...@googlemail.comwrote: Questions about the 'magic' hibernate session proxy seem to crop up a bit so I've raised a Jira to improve the docs. https://issues.apache.org/jira/browse/TAP5-2115 -- Sincerely *Boris Horvat*
Re: Tapestry Hibernate Session usage
On Mon, May 13, 2013 at 2:59 AM, Boris Horvat horvat.z.bo...@gmail.comwrote: Hi all, Hi! I have a question about what should be the best way to use hibernate session in tapestry. My environment consists of 2 layers (relevant to this). The first one would be a group of classes that represent an access point to a table. For example if I have a table student then I will have a class DAOHibernateStudent. This class receives Session object in its constructor. Doing it this way I can separate all of the queries that are available for that table into its own class. Thats strange naming, I would name the interface as StudentDAO, and implementation as just StudentDAOImpl. Note that you can also @Inject session to your DAO, you don't have to pass it through the constructor. Btw, in my projects I never put @CommitAfter annotations in this layer. In this case I can do more than one DAO-method-call in a single transaction. The second layer is a class called Manager that implements business logic. This layer has fields that represent different DAOHibernate* classes. They are all passed down using constructor. This way I can keep my business logic in a special class which will communicate with different table using different DAOHibernate* objects Again, you don't have to pass DAO instances via constructor, use @Inject. Having one big Manager class looks like God Object anti-pattern to me -- http://en.wikipedia.org/wiki/God_object I usually have one Manager class per table, so in it would be named StudentManager in your case. Its okay having multiple different DAO instances to be injected in this ConcreteManager class also, as well as another manager classes if you wish. Usually I put most of @CommitAfter annotations on this layer, some of them goes to page classes event handlers directly. Depends on use-case. I use @Inject annotation to inject manager into a page Lets imagine that I want to create a new Student. So my code would call a Manager's method createStudent(some data) which would then use a few of the DAO classes to do all sorts of stuff (e.g. create a student, register subjects for him, assign him a mentor, add him to a student group, send notification email and so on...). The problem that I see here is that since all of those DAO classes are independent I need to use few Session objects as each one will receive its own session object. So here are my questions. As far as I know in tapestry there is only one instance of Session object per request (at least by default) -- its a per-thread proxy. And this Session instance is shared across all your DAO/Manager instances. 1. Will every time when someone loads/refreshes/opens the page a new Manager class be created which will in return create a new DAOHibernate* objects and each one will receive a new Session object? There are only two scopes for tapestry services now: SINGLETON and PERTRHEAD http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ScopeConstants.html So if you bind your service via AppModule then by default you declare singleton instance. So only one instance of your Manager/DAO classes will be created and injected to your page instance. Btw, there's also only once instance of your page class will be created and shared across all requests. 2. Is it a good idea to use different session objects for the same transaction I guess (yea I know that it is not good idea so moving to the next question) As I said above, you usually have one Session object per request, and its okay. Since you will use single session instance you will have common first-level cache for all your request-scoped-queries, which is also good, I think. 3. How should this problem be solved? Should I pass new session object to manager and then pass it as a method parameter to the DAOHibernate* Leave session management to tapestry and only think about transaction scope, i.e. where to put @CommitAfter annotations. Use @Inject to inject sessions and other tapestry services to your classes. 4. Any general tips about this approach? Thanks all, Cheers -- Sincerely *Boris Horvat* -- Dmitry Gusev AnjLab Team http://anjlab.com
Re: Tapestry Hibernate Session usage
Hi Dmitry Please ignore the naming as I haven't really user he real names here as this is just an example (the project also has nothing to do with Students but it is easier for the explanations :) ). In all fairness though I do prefer to append DAOService in front as it allows me to search for the class more easily (If my page, service and domain class all start with Student it is annoying to find anything) The @CommitAfter it is my manager that has this class not the DAO's so I guess why use the same approach As for the constructor and @Inject annotation I know that I can use it but in that way I restrain my self to Tapestry (or Spring), which is not the case if I use constructor. I am aware of the God anti pattern and while there is fine line between that and my code I dont think I have crossed it as I have more then one manager. They represent an area of business logic and basically they are place where transaction annotation is put. Still it is something to keep in mind I agree. I think now I understand a bit more about the Session object in Tapestry. So yes if it is shard across all of my DAO object that would be what the behavior what I need. Do you know any place where I can read a bit about it? I am interested it as from what I can see in my code constructor is only called once (you also confirmed this) so I was wondering how does it switch the Session object each time? You mention it is a proxy so I guess that is how it replaces it, right? Thanks for the reply, Cheers, Boris On Mon, May 13, 2013 at 10:09 AM, Dmitry Gusev dmitry.gu...@gmail.comwrote: On Mon, May 13, 2013 at 2:59 AM, Boris Horvat horvat.z.bo...@gmail.com wrote: Hi all, Hi! I have a question about what should be the best way to use hibernate session in tapestry. My environment consists of 2 layers (relevant to this). The first one would be a group of classes that represent an access point to a table. For example if I have a table student then I will have a class DAOHibernateStudent. This class receives Session object in its constructor. Doing it this way I can separate all of the queries that are available for that table into its own class. Thats strange naming, I would name the interface as StudentDAO, and implementation as just StudentDAOImpl. Note that you can also @Inject session to your DAO, you don't have to pass it through the constructor. Btw, in my projects I never put @CommitAfter annotations in this layer. In this case I can do more than one DAO-method-call in a single transaction. The second layer is a class called Manager that implements business logic. This layer has fields that represent different DAOHibernate* classes. They are all passed down using constructor. This way I can keep my business logic in a special class which will communicate with different table using different DAOHibernate* objects Again, you don't have to pass DAO instances via constructor, use @Inject. Having one big Manager class looks like God Object anti-pattern to me -- http://en.wikipedia.org/wiki/God_object I usually have one Manager class per table, so in it would be named StudentManager in your case. Its okay having multiple different DAO instances to be injected in this ConcreteManager class also, as well as another manager classes if you wish. Usually I put most of @CommitAfter annotations on this layer, some of them goes to page classes event handlers directly. Depends on use-case. I use @Inject annotation to inject manager into a page Lets imagine that I want to create a new Student. So my code would call a Manager's method createStudent(some data) which would then use a few of the DAO classes to do all sorts of stuff (e.g. create a student, register subjects for him, assign him a mentor, add him to a student group, send notification email and so on...). The problem that I see here is that since all of those DAO classes are independent I need to use few Session objects as each one will receive its own session object. So here are my questions. As far as I know in tapestry there is only one instance of Session object per request (at least by default) -- its a per-thread proxy. And this Session instance is shared across all your DAO/Manager instances. 1. Will every time when someone loads/refreshes/opens the page a new Manager class be created which will in return create a new DAOHibernate* objects and each one will receive a new Session object? There are only two scopes for tapestry services now: SINGLETON and PERTRHEAD http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ScopeConstants.html So if you bind your service via AppModule then by default you declare singleton instance. So only one instance of your Manager/DAO classes will be created and injected to your page instance. Btw, there's also only once instance of your page class will be created and shared across all
Tapestry Hibernate Session usage
Hi all, I have a question about what should be the best way to use hibernate session in tapestry. My environment consists of 2 layers (relevant to this). The first one would be a group of classes that represent an access point to a table. For example if I have a table student then I will have a class DAOHibernateStudent. This class receives Session object in its constructor. Doing it this way I can separate all of the queries that are available for that table into its own class. The second layer is a class called Manager that implements business logic. This layer has fields that represent different DAOHibernate* classes. They are all passed down using constructor. This way I can keep my business logic in a special class which will communicate with different table using different DAOHibernate* objects I use @Inject annotation to inject manager into a page Lets imagine that I want to create a new Student. So my code would call a Manager's method createStudent(some data) which would then use a few of the DAO classes to do all sorts of stuff (e.g. create a student, register subjects for him, assign him a mentor, add him to a student group, send notification email and so on...). The problem that I see here is that since all of those DAO classes are independent I need to use few Session objects as each one will receive its own session object. So here are my questions. 1. Will every time when someone loads/refreshes/opens the page a new Manager class be created which will in return create a new DAOHibernate* objects and each one will receive a new Session object? 2. Is it a good idea to use different session objects for the same transaction I guess (yea I know that it is not good idea so moving to the next question) 3. How should this problem be solved? Should I pass new session object to manager and then pass it as a method parameter to the DAOHibernate* 4. Any general tips about this approach? Thanks all, Cheers -- Sincerely *Boris Horvat*