Hi,
I have two schemas on oracle DB. First with EntityA and second with EntityB. In each schemas tables have composite primary key (id and tenantId). But tables between schemas are connected with naturalId and tenantId. I want to join these tables on tentant_id and natural_id. When i’m trying this i got this exception.
It legacy DB and I cant change it.
Maybe similar: JPA error - "not mapped to a single property"
Caused by: org.hibernate.AnnotationException: referencedColumnNames(TENANT_ID, TAX_NUMBER) of org.hibernate.bugs.NonPkCompositeKey$EntityB.entityBSet referencing org.hibernate.bugs.NonPkCompositeKey$EntityA not mapped to a single property
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:321)
at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1611)
Code:
package org.hibernate.bugs;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;
import org.junit.Before;
import org.junit.Test;
public class NonPkCompositeKey {
@Before
public void init() {
Persistence.createEntityManagerFactory("templatePU");
}
@Test
public void mappingTest() throws Exception {
}
@Entity
public static class EntityA {
@EmbeddedId
private TenantId id;
@Column(name = "TAX_NUMBER")
private Long entityB_businnesId;
@OneToMany
@JoinColumns({
@JoinColumn(name = "TENANT_ID", referencedColumnName = "TENANT_ID"),
@JoinColumn(name = "TAX_NUMBER", referencedColumnName = "TAX_NUMBER")
})
private Set<EntityB> entityBSet;
}
@Entity
public static class EntityB {
@EmbeddedId
private TenantId id;
@Column(name = "TAX_NUMBER")
private Long entityB_businnesId;
}
@Embeddable
public static class TenantId implements Serializable {
private Long id;
@Column(name = "TENANT_ID")
private Long tenantId;
}
}
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="templatePU" transaction-type="RESOURCE_LOCAL">
<description>Hibernate test case template Persistence Unit</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.pool_size" value="5"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.max_fetch_depth" value="5"/>
<property name="hibernate.cache.region_prefix" value="hibernate.test"/>
<property name="hibernate.cache.region.factory_class"
value="org.hibernate.testing.cache.CachingRegionFactory"/>
<!--NOTE: hibernate.jdbc.batch_versioned_data should be set to false when testing with Oracle-->
<property name="hibernate.jdbc.batch_versioned_data" value="true"/>
<property name="javax.persistence.validation.mode" value="NONE"/>
<property name="hibernate.service.allow_crawling" value="false"/>
<property name="hibernate.session.events.log" value="true"/>
</properties>
</persistence-unit>
</persistence>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hibernate.testcasetemplate</groupId>
<artifactId>test-case-template-hibernate-orm5</artifactId>
<version>1.0.0.Final</version>
<name>Hibernate ORM 5 Test Case Template</name>
<properties>
<version.com.h2database>1.3.176</version.com.h2database>
<version.junit>4.12</version.junit>
<!--<version.org.hibernate>5.3.1.Final</version.org.hibernate>-->
<version.org.hibernate>5.2.17.Final</version.org.hibernate>
<version.org.slf4j>1.7.2</version.org.slf4j>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${version.org.hibernate}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-testing</artifactId>
<version>${version.org.hibernate}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.com.h2database}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${version.org.slf4j}</version>
</dependency>
<!-- Not necessary for ORM 5.2 and above -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${version.org.hibernate}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-java8</artifactId>
<version>${version.org.hibernate}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
when i change join to PK it works:
package org.hibernate.bugs;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.OneToMany;
import javax.persistence.Persistence;
import org.junit.Before;
import org.junit.Test;
public class NonPkCompositeKey {
@Before
public void init() {
Persistence.createEntityManagerFactory("templatePU");
}
@Test
public void mappingTest() throws Exception {
}
@Entity
public static class EntityA {
@EmbeddedId
private TenantId id;
@Column(name = "TAX_NUMBER")
private Long entityB_businnesId;
@OneToMany
@JoinColumns({
@JoinColumn(name = "TENANT_ID", referencedColumnName = "TENANT_ID"),
@JoinColumn(name = "ID", referencedColumnName = "ID")
})
private Set<EntityB> entityBSet;
}
@Entity
public static class EntityB {
@EmbeddedId
private TenantId id;
@Column(name = "TAX_NUMBER")
private Long entityB_businnesId;
}
@Embeddable
public static class TenantId implements Serializable {
private Long id;
@Column(name = "TENANT_ID")
private Long tenantId;
}
}