简体   繁体   English

Liferays Service Builder - 多对多关系

[英]Liferays Service Builder - many-to-many relations

I'm trying to create a many-to-many between my own entity and the liferay Group entity.我正在尝试在我自己的实体和 liferay Group 实体之间创建many-to-many My service.xml looks like this我的 service.xml 看起来像这样

<entity name="EntityA" local-service="true" remote-service="false">

    <column name="entityAId" type="long" primary="true" />

    <column name="title" type="String" />
    <column name="summary" type="String" />
    <column name="authorId" type="long" />

    <column name="attachments" type="Collection" entity="EntityAAttachment" mapping-key="entityAId" />
    <column name="groups" type="Collection" entity="com.liferay.portal.Group" mapping-table="EntityAs_Groups" />

</entity>

According to the DTD of the service.xml this should generate a many-to-many relation but I only get this根据 service.xml 的 DTD,这应该生成多对多关系,但我只得到这个

Method public java.util.List com.liferay.portal.tools.servicebuilder.ServiceBuilder.getMappingEntities(java.lang.String) throws java.io.IOException threw an exception when invoked on com.liferay.portal.tools.servicebuilder.ServiceBuilder@21ff3fcf
The problematic instruction:
----------
==> list serviceBuilder.getMappingEntities(column.mappingTable) as mapColumn [on line 201, column 49 in com/liferay/portal/tools/servicebuilder/dependencies/model_impl.ftl]
----------
Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: Method public java.util.List com.liferay.portal.tools.servicebuilder.ServiceBuilder.getMappingEntities(java.lang.String) throws java.io.IOException threw an exception when invoked on com.liferay.portal.tools.servicebuilder.ServiceBuilder@21ff3fcf
    at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
    at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
    at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Environment.visit(Environment.java:299)
    at freemarker.core.CompressedBlock.accept(CompressedBlock.java:73)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.IfBlock.accept(IfBlock.java:82)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:79)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:179)
    at freemarker.core.Environment.visit(Environment.java:417)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:102)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Environment.process(Environment.java:190)
    at freemarker.template.Template.process(Template.java:237)
    at com.liferay.portal.freemarker.FreeMarkerUtil.process(FreeMarkerUtil.java:49)
    at com.liferay.portal.freemarker.FreeMarkerUtil.process(FreeMarkerUtil.java:39)
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder._processTemplate(ServiceBuilder.java:4447)
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder._createModelImpl(ServiceBuilder.java:2420)
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder.<init>(ServiceBuilder.java:1023)
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder.<init>(ServiceBuilder.java:404)
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder.main(ServiceBuilder.java:176)
Caused by: java.lang.NullPointerException
    at com.liferay.portal.tools.servicebuilder.ServiceBuilder.getMappingEntities(ServiceBuilder.java:1366)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:840)
    at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
    ... 32 more

What I'm doing wrong here?我在这里做错了什么? I'm using the latest Liferay stable 6.0.5我正在使用最新的Liferay stable 6.0.5

This is an unresolved bug in Liferay: https://issues.liferay.com/browse/LPS-49769这是 Liferay 中未解决的错误: https://issues.liferay.com/browse/LPS-49769

Changing the lexicographical order of your entities might solve this problem but resolve in incorrect generated source code.更改实体的字典顺序可能会解决此问题,但会解决生成的源代码不正确。

Potential workaround by Mike Lenox athttps://www.liferay.com/community/forums/-/message_boards/message/41347203 : Mike Lenox 在https://www.liferay.com/community/forums/-/message_boards/message/41347203的潜在解决方法:

Potential workaround: I have a large model with a bunch of many-to-many mappings that always worked fine.潜在的解决方法:我有一个大型 model ,其中包含一堆总是可以正常工作的多对多映射。 I eventually stumbled across this bug when adding a new mapping.我最终在添加新映射时偶然发现了这个错误。 I finally noticed that some of my relationships should have triggered the bug, but didn't (lexigraphic order was greater than).我终于注意到我的一些关系应该触发了这个错误,但没有(字典顺序大于)。 At first I couldn't figure out why the old ones worked, but the new ones failed.起初我无法弄清楚为什么旧的有效,但新的却失败了。 Turns out that if you have a backwards many-to-many in the target entity, the builder works fine.事实证明,如果您在目标实体中有一个向后的多对多,则构建器可以正常工作。

For instance, add a fooList attribute to FooBar to correspond to the fooBarList in Foo, both using the same mapping-table..例如,将 fooList 属性添加到 FooBar 以对应 Foo 中的 fooBarList,两者都使用相同的映射表。

I suppose that this would only work for 2 custom entities unless you modify LR.我想这仅适用于 2 个自定义实体,除非您修改 LR。

Another workaround is to define the mapping yourself as an entity, as suggested by http://blog.d-vel.com/home/-/blogs/service-builder-e-relazioni-many-to-many (in Italian):另一种解决方法是将映射自己定义为实体,如http://blog.d-vel.com/home/-/blogs/service-builder-e-relazioni-many-to-many (意大利语)所建议的那样:

<entity name="Autore_Libro" local-service="true">
 <column name="autoreId" type="long" primary="true" />
 <column name="libroId" type="long" primary="true" />
</entity>

I am pretty sure you can not make one-to-many nor many-to-many relationship between your entities and portal entities.我很确定您不能在实体和门户实体之间建立一对多或多对多的关系。 At least not directly using the Service Builder.至少不直接使用 Service Builder。 Take into account that your portlet and the portal are separate contexts.考虑到您的 portlet 和门户是独立的上下文。

And as suggested in other answer, NO.正如其他答案所建议的那样,不。 NEVER mess with the portal-impl.jar.永远不要与门户 impl.jar 混淆。 It is highly discouraged.这是非常不鼓励的。

I would suggest to simulate this relationship implementing the required methods in EntityAServiceImpl and EntityALocalServiceImpl classes.我建议模拟这种关系,在 EntityAServiceImpl 和 EntityALocalServiceImpl 类中实现所需的方法。 I think this will be the cleanest way to go.我认为这将是 go 最干净的方法。

Have a look at this..看看这个。。

https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/writing-local-service-classes https://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/writing-local-service-classes

Hope that helps希望有帮助

Lferay group entity,service and implementations are in portal-impl.jar which is under ROOT/web-inf/lib, so if you are trying to use that entity their implementation and service are out of scope, then you have two choices, either you move portal-impl to the global classpath of your runtime (which a bad choice cause you'll have to move all the other libs too) or you move portal-impl to your portlet class path (which is a bad choice too).. The best solution is to use a hook so portal-impl will be reachable..then move the lib that service-builder generates to global class path of your server tomcat/lib/ext so it will be in the scope of your portlet.it works fine for me. Lferay 组实体、服务和实现在 Portal-impl.jar 中,它位于 ROOT/web-inf/lib 下,因此如果您尝试使用该实体,它们的实现和服务不在 scope 中,那么您有两个选择,要么您将 portal-impl 移动到运行时的全局类路径(这是一个糟糕的选择,因为您也必须移动所有其他库),或者您将 portal-impl 移动到您的 portlet class 路径(这也是一个糟糕的选择)。 . 最好的解决方案是使用一个hook ,这样portal-impl 就可以访问了。然后将服务生成器生成的lib 移动到服务器tomcat/lib/ext 的全局class 路径中,这样它将在您的portlet 的scope 中。这对我来说可以。 Add a reference before enclosing your entity在附上您的实体之前添加参考

<reference package-path="com.liferay.portal" entity="Group" />
  1. deploy the hook部署钩子
  2. it will generate the necessary tables它将生成必要的表
  3. stop tomcat停止 tomcat
  4. Move the lib to global classpath将库移动到全局类路径
  5. restart Tomcat重启 Tomcat

for more on Liferay Servie builder Check out this post.有关 Liferay Servie 构建器的更多信息,请查看此帖子。

http://liferaydemystified.blogspot.com/2011/04/mvc-portlet-development-service-builder.html http://liferaydemystified.blogspot.com/2011/04/mvc-portlet-development-service-builder.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM