Liferay中使用开箱的portlet时自定义关联表的事务保持

Following are the important points that a Liferay Architect must make note of in order to work with Transactions in Liferay

  1. The entry point to transaction (start of transaction boundary) in Liferay service is the <Entity>LocalServiceImpl class. Hence, while firing DML oriented methods like update, insert and delete on X Entity from Y do not use make calls to XLocalServiceUtil or XLocalService as this will result in two transaction boundaries – one for entity X and the other for entity Y. Relate the two entities through service.xml file (one to many or many to many based on your domain model) or else refer one entity in the other using <reference… in service.xml file. For e.g. if you want to make call on X entity from YLocalServiceImpl then in service.xml file while configuring Y Entity put

    <reference entity="X" package-path="com.company.project.X"></reference>

    On building the service, you will have access to xPersistence in YLocalServiceImpl. You can now make calls toxPersistence for update, insert and delete. <reference… tag is exactly for this reason. You can also include something like<reference entity="User" package-path="com.liferay.portal"></reference>to get the userPersistence object in your Entity. Then the calls to your entity and userPersistence will be the part of same transaction. In other words, updates to your tables and user_ table will be part of same transaction – either everything will commit or evrerything will be rolledback on encounter PortalException or SystemException.

  2. Ensure that your database supports transactions; yes ! this is needless to say but then if you are using MySQL, the database engine other MyISAM does not support transactions. You must useInnoDB as the database engine for your tables.
  3. As you know Liferay Entity code is generated by service builder and you get an interface called XLocalService. It is this interface which is marked with Transactional Annotation. It is set such that if you throwPortalException orSystemException from any of the methods, Hibernate Transaction Manager will rollback the transaction. Hence on violation of any business rule in the custom business-service method of XLocalServiceImpl if you want to rollback the transaction, you must throw either PortalException or SystemException.

FROM: http://www.liferayaddicts.net/blogs/-/blogs/transaction-management-with-liferay-service

前半部分为转载,本文以用户注册为例。下面为原创内容

1.本文中创建了一个portlet。创建一张表。此表名为UserInfo.有id 和userId.以userId与User_ 表相关联。

2.

参照上文内容 在UserInfoPortlet的service.xml中的UserInfo 的  entity中 加入

<reference package-path="com.liferay.portal" entity="Company" />
		<reference package-path="com.liferay.portal" entity="Contact" />
		<reference package-path="com.liferay.portal" entity="Group" />
		<reference package-path="com.liferay.portal" entity="Organization" />
		<reference package-path="com.liferay.portal" entity="PasswordPolicy" />
		<reference package-path="com.liferay.portal" entity="PasswordPolicyRel" />
		<reference package-path="com.liferay.portal" entity="Role" />
		<reference package-path="com.liferay.portal" entity="User" />
		<reference package-path="com.liferay.portal" entity="UserGroup" />
		<reference package-path="com.liferay.portal" entity="UserGroupRole" />
        <reference package-path="com.liferay.mail" entity="Mail" />
		<reference package-path="com.liferay.portlet.announcements" entity="AnnouncementsDelivery" />
		<reference package-path="com.liferay.portlet.asset" entity="AssetEntry" />
		<reference package-path="com.liferay.portlet.blogs" entity="BlogsStatsUser" />
		<reference package-path="com.liferay.portlet.documentlibrary" entity="DLFileRank" />
		<reference package-path="com.liferay.portlet.expando" entity="ExpandoValue" />
		<reference package-path="com.liferay.portlet.messageboards" entity="MBBan" />
		<reference package-path="com.liferay.portlet.messageboards" entity="MBMessage" />
		<reference package-path="com.liferay.portlet.messageboards" entity="MBStatsUser" />
		<reference package-path="com.liferay.portlet.messageboards" entity="MBThreadFlag" />
		<reference package-path="com.liferay.portlet.shopping" entity="ShoppingCart" />
		<reference package-path="com.liferay.portlet.social" entity="SocialActivity" />
		<reference package-path="com.liferay.portlet.social" entity="SocialRequest" />

build之后开始复制UserLocalServiceImpl.java的创建账户的对应方法至UserInfoLocalServiceImpl.java

3.eclipse提示缺少portal-impl.jar包里的引入。引入此包 编译 部署,运行时发生 NoClassDefException.

4.将portal-impl.jar复制进/WEB-INF/lib 编译,报错。英文提示说这个jar包里面有很多单例模式的实现。如果这样使用 会导致debug困难。

请尝试使用不需要引入这些类的解决方案。
5.百度和google发现PortalClassInvoker这个类应该是可以解决这个问题。修改代码 编译 部署。成功
6.问题 3 4 5的解决方案:
    不要加portal-impl.jar。使用PortalClassInvoker.invoke(…);方法替代portal-impl.jar里的类的方法。