Liferays Service Builder - 多对多关系

发布于 2024-11-14 17:55:54 字数 4595 浏览 3 评论 0原文

我正在尝试在我自己的实体和 liferay Group 实体之间创建一个多对多。我的 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>

根据 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

我在这里做错了什么?我正在使用最新的 Liferay stable 6.0.5

I'm trying to create a many-to-many between my own entity and the liferay Group entity. My service.xml looks like this

<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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鸢与 2024-11-21 17:55:54

这是 Liferay 中未解决的错误:https://issues.liferay.com/browse/LPS-49769

更改实体的字典顺序可能会解决此问题,但会解决生成的源代码不正确的问题。

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

潜在的解决方法:我有一个带有一堆的大模型
多对多映射始终运行良好。我最终跌倒了
添加新映射时会遇到此错误。我终于注意到有些
我的人际关系应该触发了这个错误,但没有
(词典顺序大于)。起初我无法弄清楚
为什么旧的有效,但新的却失败了。事实证明,如果
您在目标实体(构建器)中有一个向后的多对多
工作正常。

例如,给FooBar添加一个fooList属性来对应
Foo 中的 fooBarList 都使用相同的映射表..

我认为这仅适用于 2 个自定义实体,除非您
修改LR。

另一种解决方法是将映射自己定义为实体,如 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>

This is an unresolved bug in 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 at 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. 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..

I suppose that this would only work for 2 custom entities unless you
modify 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):

<entity name="Autore_Libro" local-service="true">
 <column name="autoreId" type="long" primary="true" />
 <column name="libroId" type="long" primary="true" />
</entity>
帝王念 2024-11-21 17:55:54

我很确定您无法在实体和门户实体之间建立一对多或多对多的关系。至少不直接使用Service Builder。请考虑您的 portlet 和门户是独立的上下文。

正如其他答案中所建议的,不。永远不要弄乱portal-impl.jar。这是非常不鼓励的。

我建议模拟这种关系,在 EntityAServiceImpl 和 EntityALocalServiceImpl 类中实现所需的方法。我认为这将是最干净的方式。

看看这个..

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

希望有帮助

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. Take into account that your portlet and the portal are separate contexts.

And as suggested in other answer, NO. NEVER mess with the portal-impl.jar. It is highly discouraged.

I would suggest to simulate this relationship implementing the required methods in EntityAServiceImpl and EntityALocalServiceImpl classes. I think this will be the cleanest way to go.

Have a look at this..

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

Hope that helps

咿呀咿呀哟 2024-11-21 17:55:54

Lferay 组实体、服务和实现位于 ROOT/web-inf/lib 下的 Portal-impl.jar 中,因此,如果您尝试使用该实体,它们的实现和服务超出了范围,那么您有两种选择:您将portal-impl 移动到运行时的全局类路径(这是一个错误的选择,因为您还必须移动所有其他库),或者将portal-impl 移动到您的portlet 类路径(这也是一个错误的选择)。 。
最好的解决方案是使用hook,以便可以访问portal-impl。然后将service-builder生成的lib移动到服务器tomcat/lib/ext的全局类路径,这样它将位于你的 portlet.it 的范围对我来说效果很好。
在包含实体之前添加引用

<reference package-path="com.liferay.portal" entity="Group" />
  1. 部署钩子
  2. 它将生成必要的表
  3. 停止tomcat
  4. 将lib移动到全局类路径
  5. 重新启动Tomcat

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.
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
  4. Move the lib to global classpath
  5. restart Tomcat
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文