我正在尝试使用外键和固定值映射集合(类型映射)作为键/映射参数。
我有几个产品类型表和一个包含产品名称等内容的语言表。
现在假设我们有一个附件表(显然)包含附件,然后附件的名称存储在语言表中,其中包含language.id = accessory.id和language.type ='accessory'。 map-key应该是language.lang字段,一个语言代码字符串。
现在,无论我尝试过什么,我都无法将“language.type ='accessory'”部分放在右边,不喜欢多个关键元素,反过来又不允许使用元素。
我也尝试使用复合组件作为foreignKey,默认情况下设置常量,但这样做也不起作用:
<class name="AccessoryTypes"
table="accessorytypes">
<id name="id" column="id" type="java.lang.Long" unsaved-value="0">
<generator class="identity"></generator>
</id>
<map name="Name" table="ProductCode">
<key column="CompositeId" />
<map-key column="Language" type="string" />
<one-to-many class="ProductCode" />
</map>
</class>
<class name="Language"
table="Language">
<composite-id name="compositeId" class="languageKey">
<key-property name="Type"></key-property>
<key-property name="Id"></key-property>
</composite-id>
<property name="Lang" type="string"></property>
<property name="Value"></property>
</class>
当然有适当的课程。这种方法没有错误,但是没有填充Accessory类的HashMap ......
任何帮助都将不胜感激,谢谢。
[编辑] 我现在尝试使用property-ref作为ziodberg建议,首先是不是这样的:
<class name="AccessoryTypes"
table="accessorytypes">
<id name="id" column="id" type="java.lang.Long" unsaved-value="0">
<generator class="identity"></generator>
</id>
<properties name="CompositeId" >
<property name="id" />
<property name="Type" formula="'accessory'" />
</properties>
<map name="Name" table="ProductCode">
<key property-ref="CompositeId" />
<map-key column="Language" type="string" />
<one-to-many class="ProductCode" />
</map>
</class>
和
<class name="com.swissclick.wesco.web.model.ProductCode"
table="ProductCode">
<composite-id class="com.swissclick.wesco.web.model.ProductCodeKey" mapped="true">
<key-property name="Type"></key-property>
<key-property name="id"></key-property>
</composite-id>
<property name="Language" type="string"></property>
<property name="Value"></property>
</class>
但这也不起作用,它给出了
org.hibernate.MappingException: collection foreign key mapping has wrong number of columns: AccessoryTypes.Name type: component[Id,Type]
没有在谷歌上发现任何有用的信息。
任何想法?
答案 0 :(得分:2)
<强>被修改即可。所以我对你的桌面结构还不太清楚 - 这就是我在写下初步答案时抛出的东西。
我的理解是你的Language
表看起来像:
Id -- this is a PK of entity (e.g. Accessory) this entry provides localization info for
Type -- string constant describing entity type (e.g. "accessory")
Language -- language code
Value -- actual localized string
看起来对吗?如果是这样,这会引发一个问题,即您打算如何在同一实体中本地化多个字段。你不应该至少有另一列链接到属性(字段)名称吗?
无论如何,<formula>
确实不支持<key>
作为type
的一部分(我可能已经宣誓就是这样),所以你在这里的选择非常有限:
Accessory
表格中添加Language
作为实际列,并将其作为复合ID的一部分进行映射;然后,您可以使用复合键映射get()
地图。应该工作,但相当丑陋。Language
,假设适当的复合ID),当前语言更容易,并且(有足够的缓存配置)更快。更新详细说明上述#3:
首先,让我澄清一下 - 我假设您的本地化字符串在运行时是用户可编辑的。如果情况并非如此,我强烈建议完全放弃该表,而是使用资源包。
我将type
映射为一个单独的实体id
,language
,property_name
和(如果您需要为多个属性执行此操作){{1} }作为复合id的一部分。您实体的实际可本地化属性(例如ProductName
上的AccessoryType
)将是暂时的。然后,您可以通过执行以下操作手动为实体加载适当的本地化字符串:
AccessoryType accessory = ...;
Language language = (Language) session.get(Language.class,
new LanguageKey("accessory", accessory.id, "en_US", "productName"));
accessory.setProductName(language.getValue());
你甚至可以在event listener中做到这一点,假设当前选择的语言是全局可获得的(通过全局或线程本地调用) - 它将自动神奇地发生在你所有的实体上。 如果语言表相当小,您可以使用Hibernate cache it,甚至不会对此产生数据库命中。