留言板

Need Suggestion using JPA instead of Service Builder

thumbnail
Gnaniyar Zubair,修改在11 年前。

Need Suggestion using JPA instead of Service Builder

Liferay Master 帖子: 722 加入日期: 07-12-19 最近的帖子
HI,

Liferay is generating the services to persist the data into database via JPA / Hibernate through Service Builder. But It doesn't support for foreign key, one-to-many, many-to-many,etc. So my client wants to handle the DAO layer directly through JPA with Eclipse Hyperlink or Hibernate without touching Service Builder.

Because of mentioned limitations in liferay's service builder, is it the best way to handle via JPA ? As per our requirement, we dont need to produce any webservices . At this situation, what is your suggestion whether we can go for JPA or Service Builder ?

Please throw some lights on this.

-Gnaniyar Zubair
thumbnail
David H Nebinger,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Legend 帖子: 14915 加入日期: 06-9-2 最近的帖子
1. Use JNDI to lookup database connections. Define them using a connection pool.
2. Isolate out as a separate jar if multiple, separate plugins (wars) will be using them. Potentially deploy to global lib directory of container to facilitate reuse, but this incurs server restart to deploy update.

Your biggest issue will be runtime resource consumption and synchronization. With multiple separate WARs all using hibernate/jpa separately, you could end up w/ too many connections to the database. Also you'll need to disable the caching otherwise you'll face issues w/ possible stale data.

In the end, I'd recommend your clients stick with SB. Even though it is not perfect, it will not have these kinds of issues to deal with.

As far as their specific concerns:

1. Foreign Keys - SB will not generate sql scripts to create the FK constraints. But you don't need to allow SB to actually create the tables. We do not here; our DBAs create the tables with appropriate FK constraints and just use SB to create the access layer.

2. One to Many relationships - No, it's not really supported, but it's not much of a challenge either. SB will generate finders when you define one for the child entity that takes the parent key value. From a development standpoint, instead of a simple "parent.getChildren()" method on the parent object, you use a "ChildLocalServiceUtil.getChildren(parent.getId())" sort of thing.

3. Many to Many relationships - This certainly isn't handled by SB, but you can define the join table as an SB entity w/ appropriate finders to find the list for either side of the join.

The benefits of SB, though, are as follows:

1. Single access layer that is easily shared w/ all plugins. The code generated by SB operates in a single plugin, but can be shared across all portlets w/o worrying about extra database connections and/or code synchronization.

2. Single access layer allows for use of caching, since there is only one reader/writer stale data is not a concern.

3. Easily share the service jars w/ plugins w/o requiring container restart when updates are pushed.

4. SB generated code saves a huge amount of time during development. I will beat any developer generating a JPA/Hibernate layer hands-down due to the code that SB generates for me (we in fact have that competition going on right now, a separate servlet using hibernate takes significantly more time to implement changes than what it takes me to add to service.xml and rebuild the services).

Comparing the benefits to the missing pieces, personally I'd rather deal w/ the lack of support for O-2-M and M-2-M than I would dealing w/ a hibernate/jpa implementation, and I think if your clients understood the difference, they'd be onboard too...
thumbnail
Gnaniyar Zubair,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Master 帖子: 722 加入日期: 07-12-19 最近的帖子
David,

Thanks for detailed explanation about Service builder . Really it will be helpful to me to recommend service builder instead of JPA / Hibernate.

Liferay's Message Board shows that you are a Legend because of your forum counting. But really you are a Liferay Legend. emoticon

Thanks again for your valid information.

- Gnaniyar Zubair
thumbnail
Gnaniyar Zubair,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Master 帖子: 722 加入日期: 07-12-19 最近的帖子
David,

Sorry to disturb you and Thanks again for your detailed explanation . As you mentioned Servicebuilder doesn't support one-many and many-to many, so we can handle those relationship by our own methods. ok fine

But my client is afraid of some queries :

1. SB generates lot of auto generated classes. For example, if we have 10 entities in one service.xml, then Service Builder will generate more than 80 files in IMPLEMENTATION LAYER in

model-impl folders
and
service--> base, impl and persistence folders


Also in INTERFACE LAYER, more than 100 files in

Model , Service --> Messaging and Persistence folder
.

Maintaining and Bug tracking with all these auto generated classes is very complex .

But Using JPA, we can avoid all those files and can achieve same features with minimal classes.


2. Also I have 2 entities. BOOK and STUDENTS . I am storing studenId in BOOKS table.
[indent] By passing the studentId, I will get list of BOOKS. Then if i need to get the Students information, then i need to pass the studentId to STUDENTS table .[indent]In this scenario , Database is hitting two times one is for fetching books from BOOK table another hit is for receiving students from STUDENT table.
BookLocalServiceUtil & StudentLocalServiceUtil .[/indent][/indent]

[indent]
But in JPA , we can use mapping option to fetch the BOOK and STUDENTS details in one database hit.
[/indent]

[indent]3. If we generate big application with lot of services (entities) using SB, will it be any Memory leak?[/indent]

As they have worked with some JPA applications previously, they are very confident with handling Transaction Management and DAO layers. But now they are planning to use SB if they are cleared with above queries. As this application may handle millions of organization and sub organization members accessing services, they need to design with suitable architecture. so would be great if you clarify above things.

- Gnaniyar Zubair
thumbnail
David H Nebinger,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Legend 帖子: 14915 加入日期: 06-9-2 最近的帖子
Gnaniyar Zubair:
1. SB generates lot of auto generated classes. For example, if we have 10 entities in one service.xml, then Service Builder will generate more than 80 files. Maintaining and Bug tracking with all these auto generated classes is very complex.


You don't maintain or bug track generated code. The only files developers will edit are the service.xml file and the Xxx(Local)ServiceImpl classes. The rest of the code is boilerplate. Developers should not be making changes to them, so there's no maintenance or bug tracking the corresponds with them.

But Using JPA, we can avoid all those files and can achieve same features with minimal classes.


Even for JPA, it is still best practice to use a separate DAO per entity. With SB, you get one XxxLocalServiceImpl per entity (plus one if you've enabled remote services). Instead of having one pojo per entity, you've got an interface and a bunch of implementation classes. Big deal. You're not editing/maintaining that code, so it's not a concern.

2. In this scenario , Database is hitting two times one is for fetching books from BOOK table another hit is for receiving students from STUDENT table. But in JPA , we can use mapping option to fetch the BOOK and STUDENTS details in one database hit.


This is a known issue w/ Service Builder. Nothing I can do to help you there.

3. If we generate big application with lot of services (entities) using SB, will it be any Memory leak?


They're just extra classes. Why would anyone think that extra classes result in a memory leak?

SB is not an ORM, at least in the sense of what an ORM means today. SB is meant to solve specific problems in a portal environment, specifically that of separate plugins requiring data access to the same entities.

Imagine a system for an e-commerce site. One function is visible to users and they can submit orders. A second function is for the warehouse guys to update stock information. A third function is for managers to view the orders placed today.

In a classic servlet-based system, you would create a single web application that provided all of these functions. Here you would use JPA and the world is all puppies and flowers because, at the end of the day, you only have one reader/writer and any information cached by JPA is visible to all three functions.

In a portal-based system, however, you would create three separate portlets for the functions. And you'd probably create them as separate portlet plugins to ensure that coupling was kept to a minimum.

So you decide on the JPA route and build your JPA stuff. Since there's no easy way to share code among separate web apps, you copy your JPA stuff to each of the 3 portlets. You build them and deploy them, place them on the portal pages, and everything looks good.

Now, however, it is important to note that you have 3 separate database readers/writers, and information that they cache is not visible to the others. So user does a query to see what quantity of a widget you have in stock, and the number comes back as zero. Warehouse does an update and says there's now 10. User does a refresh, but since the information was already retrieved and is probably cached, they still see the quantity is zero. Management does a query and sees 2 orders, meanwhile 5 new users submit orders; management does a refresh and, since the data was already retrieved and cached, still only sees the 2 orders. Etc. So yes, here you would have your smaller class count and your single db call to retrieve an object graph, but the data being returned will likely be stale, so having those advantages really didn't help at all.

SB gets you back to a single reader/writer for multiple portlets. The three portlets in question would use the same SB service, and as each individual portlet is doing an update, there is no stale cache data that the other two need to worry about.

All that said, you can use JPA if you insist, but you have to be very specific when it comes to implementation:

1. Any plugin using the JPA framework must be in the same plugin. So from the 3 portlet example, these would all need to be in the same plugin project and deployed in a single war. This is the only way to mitigate the stale cached data issue, but the cost is the tight coupling of all of the plugins.
2. You won't be able to use the JPA stuff in a hook/ext, since you'd then be introducing the multiple reader/writer issues.

If I was forced to use JPA in a portal environment, I'd probably create a web service to wrap the JPA access and have the individual portlets invoke the web service. This would introduce more overhead in using JPA (for the marshalling and unmarshalling overhead of invoking a web service), but the portlets could all be separate plugins and it could also be used in a hook or ext plugin.
Dionysos Kechrologos,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

New Member 帖子: 5 加入日期: 14-11-3 最近的帖子
Hello!

I have read around the forum about Service Builder and its benefits. An I understand its merits at some extent. But I have some questions that puzzle me.
1. SB's main role is to create a single entry point to the database (usually other than liferay's I assume). It does that in order to avoid caching problems, limit connection resources overflow etc.
2. It is mentioned that SB creates an interface jar for client portlets to use, and an implementation jar that offers the persistence service. Correct?

3. Ok. So how SB differs from the case where I built a persistance.ear where I use Enterprise Beans with Remote Access via Interface-view of beans. Doesn't this offer the same benefits? That is, I can use JPA in persistance.ear, abstract away with beans that can be called by any portlet (even via an intranet network etc.). At the same time, because I have to define interface views of my beans, I have the interface to use in portlets or whatever in order to have a decoupled access by many client points, yet with one connection pool, caching and transaction management.

4. As a developer I don't have to bother in this case how data are passed or how methods are called between client - persisntace.war because JavaEE does that for me, not?
5. In what way SB may differ with this approach (technically)? Are there any pitfall by following this approach?

My questions are from a technically point of view, meaning that I understand that SB already does the above plus offering more by generating code etc.
If for some (crazy) reason I wanted to implement my system like I described, will I have any problems in respect to SB, besides loosing the out of the box functionality offered by it?

I apologize for my long story here ^_^.

Thank you
Dionysos Kechrologos
thumbnail
David H Nebinger,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Legend 帖子: 14915 加入日期: 06-9-2 最近的帖子
Dionysos Kechrologos:
1. SB's main role is to create a single entry point to the database (usually other than liferay's I assume). It does that in order to avoid caching problems, limit connection resources overflow etc.


Right.

2. It is mentioned that SB creates an interface jar for client portlets to use, and an implementation jar that offers the persistence service. Correct?


Right.

3. Ok. So how SB differs from the case where I built a persistance.ear where I use Enterprise Beans with Remote Access via Interface-view of beans. Doesn't this offer the same benefits? That is, I can use JPA in persistance.ear, abstract away with beans that can be called by any portlet (even via an intranet network etc.). At the same time, because I have to define interface views of my beans, I have the interface to use in portlets or whatever in order to have a decoupled access by many client points, yet with one connection pool, caching and transaction management.


Right, but Liferay doesn't need a full JEE server and it doesn't take advantage of one either. Liferay deploys as, for all intents and purposes, a simple WAR file. So if you created an EAR that contained Liferay and all of your portlets well, then possibly you could get the same sort of benefit using persistence.ear. But it's questionable to me whether you would actually be able to attain the full access to the persistence stuff across all of your portlet wars, but that I guess is something you'd have to test to find out. I would bet that your Liferay installation would be so far away from a standard Liferay install that you'd have trouble getting any sort of support for it, whether here in the forums or paid support if you were using EE.

4. As a developer I don't have to bother in this case how data are passed or how methods are called between client - persisntace.war because JavaEE does that for me, not?


Right, but Liferay doesn't use or support JEE, remember?

5. In what way SB may differ with this approach (technically)? Are there any pitfall by following this approach?


SB is different as the service jar is actually just a templatized way to use reflection and serialization to cross the class loader boundary in place between web applications. When you define an entity in service.xml, SB will generate code based upon templates that knows how to use reflection and serialization. As you add methods to the impl classes and re-run SB, SB will use the new method signatures to add more reflection/serialization to the service jar for external web apps to be able to use it.

JEE and the persistence, well that too is an alternate method to share this kind of stuff across the class loader boundary (well, I think technically there is a "global" class loader at the EAR level to share classes, but the actual implementation for crossing the class loader boundary for the wars within ears, well I'm just not sure about that). I do believe that for the persistence within the EAR to work, well then all of your wars would have to be within the EAR itself for it to work.

Anyway, are there pitfalls by following this approach? Well, which approach are you referring to? For SB, well the pitfall is that you don't get a full ORM. For persistence in the ear, all of your wars have to be part of the ear and that may provide some difficulty with hot deploy features of Liferay, but you're welcome to try some of these things out for yourself.

The upshot for doing things the Liferay way, well you get app server neutrality (i.e. your developers can develop against tomcat and deploy to production JEE server as-is), you get a known tested implementation that works for Liferay whether you are using just an app server or a full JEE server (I don't know of anyone who has done persistence sharing at an EAR level yet implemented a portlet that works under the Liferay app), you get support from Liferay and the forums (if you go your own way, well then you are your own support), ...

My questions are from a technically point of view, meaning that I understand that SB already does the above plus offering more by generating code etc.
If for some (crazy) reason I wanted to implement my system like I described, will I have any problems in respect to SB, besides loosing the out of the box functionality offered by it?


Hey, don't worry about it. We've all come here from servlet and JEE development, we've all preferred to use hibernate, jpa, JEE or some other thing that SB because at the end of the day, from a pure ORM perspective, they are so much better than SB.

Yet at the same time I've seen projects using hibernate, JPA (and probably your JEE persistence ear stuff) crash and burn because of incompatibility in the portal environment where SB implementations just work (once you get over the "but this is not a full ORM" mindset).

As far as what you'd lose? Well SB entities come with so much more than just the ORM functionality. You get the ability to use Expandos with entities, so if they need to get extended in the future you wouldn't have to do table changes. You get remote web services so you can access via ajax within javascript in your portlet. You get to treat them as a full scale Liferay asset. You get to include recycle bin support. You get to integrate workflow on them (when they are assets).

No matter of persistence ear stuff is going to give you all of these things. You may not need any of this, so a JEE persistence implementation may still be an option for you, but that's going to be based on your requirements.
thumbnail
Prakash Khanchandani,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

Expert 帖子: 329 加入日期: 11-2-10 最近的帖子
David H Nebinger:
Yet at the same time I've seen projects using hibernate, JPA (and probably your JEE persistence ear stuff) crash and burn because of incompatibility in the portal environment where SB implementations just work (once you get over the "but this is not a full ORM" mindset).


You have nailed it! emoticon

Thanks for the wonderful and detailed explanation as well.

Thanks
Dionysos Kechrologos,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

New Member 帖子: 5 加入日期: 14-11-3 最近的帖子
Thank you very much for your feedback! ^_^
It helped clarify some things and gave some input for thought ;)
thumbnail
Muhammed Shakir AK Misarwala,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Junior Member 帖子: 36 加入日期: 09-2-26 最近的帖子
I agree with David in toto. There is nothing that cannot be done with SB that you can directly do with JPA.

About the number of classes - If one is passionate about clean code and code that is resilient to changes, he/she will definitely use design principles and patterns to implement his services. And when you religiously design application around principles and patterns, you will anyways end up creating the number of classes that SB creates. Now the question is - Do you want to reinvent the wheel ?

Please explore FinderImpl, Custom Persistence Class concept etc. Moreover, using SB enforces patterns among all the programmers in the team including the trainee programmers. With SB everyone knows, where to write domain service, where to write use case service, where to write custom persistence, where to write custom finders etc.

If still the decision is to ignore SB then using JPA & Hibernate in Liferay will be as same as using it elsewhere. One benefit I see here is that you will be able to switch from one ORM to the other by modifying your DAO (Use Abstract Factory to design DAOs - see DAO J2EE design pattern) classes.

Hope this helps.
thumbnail
Gnaniyar Zubair,修改在11 年前。

RE: Need Suggestion using JPA instead of Service Builder

Liferay Master 帖子: 722 加入日期: 07-12-19 最近的帖子
Thanks David and Shakir for sharing your thoughts and detailed explanation on this issue.
Savita Bangera,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

New Member 帖子: 2 加入日期: 14-4-6 最近的帖子
Hi Gnaniyar,

This post was quite informative. Gnaniyar, I am inquisitive to know what you finally implemented ? Did you use Service Builder or you opted for JPA.. I am currently in the same state as you were when you had posted this question. So your experience will surely help me decide.

Thanks & Regards
Savita
Jean-Marie Dessertaux,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

New Member 发布: 1 加入日期: 14-3-22 最近的帖子
Savita Bangera:
Hi Gnaniyar,

This post was quite informative. Gnaniyar, I am inquisitive to know what you finally implemented ? Did you use Service Builder or you opted for JPA.. I am currently in the same state as you were when you had posted this question. So your experience will surely help me decide.

Thanks & Regards
Savita



Other solution with Hibernate using Service Builder ; Hibernate autorise to use SQL requests to access target Database when the type of the target Database is known. I faced a bug in Liferay 6.1.20 Hiberante does not manage correctly complex custom sql requests for known target Database when one uses "parameterised" sql requests. The solution is to avoid using parametrised sql request. Make all the sql request as a String. Such complex requests are then correctly executed.by Hibernate in Liferay.
Hope it helps
thumbnail
Robin Nagpal,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

Junior Member 帖子: 44 加入日期: 14-11-18 最近的帖子
Liferay SB provides a lot of benefits, but just like other frameworks it does have some limitations. Think about implementing things like
  • Hibernate entities & persistence
  • JSON web services
  • Adding security
  • Multi culster cache


Theses things were really handy 3-4 years ago. Now the same can be done using Spring JPA, Spring WEB MVC, Spring Security etc.

I guess the most important thing to consider is whether you need to share your services within different protlet projects.If yes, then SB is your best bet. If you are 200% sure that one portlet project can suffice your needs, you can use other technologies independently which does provide more flexibility but requires indepth knowledge of these.
Savita Bangera,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

New Member 帖子: 2 加入日期: 14-4-6 最近的帖子
Thanks Robin and Thanks Jean for the quick response..

I want to use the service across portlets as I want to implement custom workflow in custom portlets. Access level to each portlet depends upon the role of the user and the stage of the workflow.

Had read posts wherein it was written that managing service layer if required across portlets is difficult to manage if service builder is not used hence not sure on the implementation approach
thumbnail
Robin Nagpal,修改在9 年前。

RE: Need Suggestion using JPA instead of Service Builder

Junior Member 帖子: 44 加入日期: 14-11-18 最近的帖子
Savita Bangera:
Thanks Robin and Thanks Jean for the quick response..

I want to use the service across portlets as I want to implement custom workflow in custom portlets. Access level to each portlet depends upon the role of the user and the stage of the workflow.

Had read posts wherein it was written that managing service layer if required across portlets is difficult to manage if service builder is not used hence not sure on the implementation approach



Hi Savita, different portlet project and different portlets are two different things as there can be many different portlets in a single portlet project. As I said earlier, if you have single protlet project and if you need more control, you can use spring services-jpa-hibernate without using Service Builder. But then you need to have indepth knowledge of these and fine tune things like Spring contexts, Multi VM cache etc, which SB provides out-of-box

Service builder is plain, but makes a lot of things easier.

If you have a multi portlet projects(multiple wars) and you need to share the services, then SB is your best bet.