我正在尝试按照此示例在模型中创建多对多关系,并使用 Teneo 在单独的表中使用复合键和附加列。我的模型处于休眠状态,这就是模型部分的 ecore 文件:
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="my" nsURI="test.my" nsPrefix="test">
<eClassifiers xsi:type="ecore:EClass" name="Resource">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Table(uniqueConstraints={@UniqueConstraint(columnNames={"ip","name", "revision", "type"})})"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
iD="true">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Id
 @GeneratedValue(strategy=GenerationType.AUTO)"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="resourceTags" ordered="false"
upperBound="-1" eType="#//ResourceTag" resolveProxies="false" eOpposite="#//ResourceTag/resource">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@OneToMany ( indexed = false, fetch=FetchType.EAGER, mappedBy = "resourceId", cascade=CascadeType.ALL)"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Tag">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Table(uniqueConstraints={@UniqueConstraint(columnNames={ "name"})})
@NoAuditing"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"
iD="true">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Id
 @GeneratedValue(strategy=GenerationType.AUTO)"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="resourceTags" ordered="false"
upperBound="-1" eType="#//ResourceTag" resolveProxies="false" eOpposite="#//ResourceTag/tag">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@OneToMany (indexed=false, fetch=FetchType.EAGER, mappedBy = "pk.tagid", cascade=CascadeType.ALL)"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ResourceTag">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Table(name = "ResourceTag")
"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="date" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDate"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="pk" eType="#//ResourceTagId"
resolveProxies="false">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@EmbeddedId"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="comment" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="tag" eType="#//Tag" eOpposite="#//Tag/resourceTags">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Transient"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="resource" eType="#//Resource"
eOpposite="#//Resource/resourceTags">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Transient"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ResourceTagId">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@Embeddable"/>
</eAnnotations>
<eStructuralFeatures xsi:type="ecore:EReference" name="tag" eType="#//Tag">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@ManyToOne
@JoinColumns({
	@JoinColumn(name="tagId", referencedColumnName = "id")
})"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="resource" eType="#//Resource">
<eAnnotations source="teneo.jpa">
<details key="appinfo" value="@ManyToOne
@JoinColumns({
	@JoinColumn(name="resourceId", referencedColumnName = "id")
})"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
</ecore:EPackage>
该模型生成的映射是
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="false">
<typedef name="model.EIllegalStateException" class="org.eclipse.emf.teneo.hibernate.mapping.DefaultToStringUserType">
<param name="epackage">http://www.qualcomm.com/qti/qsip/designbook/model</param>
<param name="edatatype">EIllegalStateException</param>
</typedef>
<class name="test.my.ResourceImpl" entity-name="Resource" abstract="false" lazy="false" discriminator-value="Resource" table="`resource`">
<meta attribute="eclassName" inherit="false">Resource</meta>
<meta attribute="epackage" inherit="false">http://www.qualcomm.com/qti/qsip/designbook/model</meta>
<id name="id" type="int" unsaved-value="0">
<column not-null="true" unique="false" name="`id`"/>
<generator class="native"/>
</id>
<discriminator type="string">
<column name="`dtype`" index="resourcedtype" length="255" not-null="true"/>
</discriminator>
<version name="revision" type="int">
<column not-null="true" unique="false" name="`revision`" unique-key="c0"/>
</version>
<property name="type" lazy="false" insert="true" update="true" not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`type`" unique-key="c0"/>
</property>
<property name="name" lazy="false" insert="true" update="true" not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`name`" unique-key="c0"/>
</property>
<bag name="resourceTags" inverse="true" lazy="false" cascade="all,delete-orphan">
<key update="true">
<column name="`resourcetag_resource_id`" unique="false"/>
</key>
<one-to-many entity-name="ResourceTag"/>
</bag>
</class>
<class name="test.my.TagImpl" entity-name="Tag" abstract="false" lazy="false" discriminator-value="Tag" table="`tag`">
<meta attribute="eclassName" inherit="false">Tag</meta>
<meta attribute="epackage" inherit="false">http://www.qualcomm.com/qti/qsip/designbook/model</meta>
<id name="id" type="int" unsaved-value="0">
<column not-null="true" unique="false" name="`id`"/>
<generator class="native"/>
</id>
<discriminator type="string">
<column name="`dtype`" index="tagdtype" length="255" not-null="true"/>
</discriminator>
<property name="name" lazy="false" insert="true" update="true" not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`name`" unique-key="c0"/>
</property>
<bag name="resourceTags" inverse="true" lazy="false" cascade="all,delete-orphan">
<key update="true">
<column name="`resourcetag_tag_id`" unique="false"/>
</key>
<one-to-many entity-name="ResourceTag"/>
</bag>
</class>
<class name="test.my.ResourceTagImpl" entity-name="ResourceTag" abstract="false" lazy="false" discriminator-value="ResourceTag" table="`resourcetag`">
<meta attribute="eclassName" inherit="false">ResourceTag</meta>
<meta attribute="epackage" inherit="false">http://www.qualcomm.com/qti/qsip/designbook/model</meta>
<composite-id name="pk" class="test.my.ResourceTagIdImpl" access="org.eclipse.emf.teneo.hibernate.mapping.property.EReferencePropertyHandler">
<meta attribute="eclassName" inherit="false">ResourceTagId</meta>
<meta attribute="epackage" inherit="false">http://www.qualcomm.com/qti/qsip/designbook/model</meta>
<key-many-to-one name="tag" entity-name="Tag" lazy="false">
<column not-null="false" unique="false" name="`tagid`"/>
</key-many-to-one>
<key-many-to-one name="resource" entity-name="Resource" lazy="false">
<column not-null="false" unique="false" name="`resourceid`"/>
</key-many-to-one>
</composite-id>
<discriminator type="string">
<column name="`dtype`" index="ResourceTagdtype" length="255" not-null="true"/>
</discriminator>
<property name="date" lazy="false" insert="true" update="true" not-null="false" unique="false" type="timestamp">
<column not-null="false" unique="false" name="`date`"/>
</property>
<property name="comment" lazy="false" insert="true" update="true" not-null="false" unique="false" type="java.lang.String">
<column not-null="false" unique="false" name="`comment`"/>
</property>
</class>
</hibernate-mapping>
如您所见,从 Resource 到 ResourceTag 的 oneToMany 映射由新的外键映射,因此 ResourceTag 表具有重复的列resourcetag_tag_id
,而resourcetag_resource_id
不是复合主键“resourceId”和“tagid”中的列。
我的休眠 perisitent 选项如下:
props.setProperty(PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT,
"PERSIST,REFRESH");
props.setProperty(PersistenceOptions.CASCADE_POLICY_ON_CONTAINMENT,
"ALL");
props.setProperty(PersistenceOptions.MAP_ALL_LISTS_AS_IDBAG, "false");
props.setProperty(PersistenceOptions.ALWAYS_MAP_LIST_AS_BAG, "false");
props.setProperty(PersistenceOptions.ID_FEATURE_AS_PRIMARY_KEY, "false");
props.setProperty(PersistenceOptions.ALWAYS_VERSION, "false");
props.setProperty(PersistenceOptions.JOIN_TABLE_FOR_NON_CONTAINED_ASSOCIATIONS, "false");
props.setProperty(PersistenceOptions.SET_FOREIGN_KEY_NAME, "false");
props.setProperty(PersistenceOptions.FEATUREMAP_AS_COMPONENT, "true");
我在resource.resourceTags 中@OnetoMany 关系的mappedby 属性中尝试了许多不同的组合,但所有这些组合都被teneo/hibernate 忽略了。我还尝试按照示例中的说明使用@AssociationOverride,但这对映射也没有任何影响。
我想在标签和资源之间实现双向多对多关系,它有一些额外的属性。这样,当我加载资源时,我可以自动获取标签,当我加载标签时,我可以自动获取资源。但是,使用此映射,ResourceTag 表中的额外外键列为空,因此不会获取关系。
这是模型的一个子集,我删除的这些类中包含许多其他引用。许多配置是根据其他要求定义的。