![](/img/trans.png)
[英]Foreign key must have same number of columns as the referenced primary key error, but a have no entities with composite key
[英]Foreign key must have the same number columns as the referenced primary key
我有以下實體。
package misc;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class EntityA implements Serializable {
private static final long serialVersionUID = -6740580086652468946L;
@Id
private int counter;
}
package misc;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class EntityB implements Serializable {
private static final long serialVersionUID = -1919957640470940855L;
@Id
private String name;
}
package misc;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class EntityC implements Serializable {
private static final long serialVersionUID = -4676412878199289178L;
@Id
private String name;
}
package misc;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OrderColumn;
import javax.persistence.UniqueConstraint;
@Entity
public class HistoricalEntity implements Serializable {
private static final long serialVersionUID = 4889420648637014496L;
@Id
@ManyToOne
@JoinColumn
private EntityA entityA;
@Id
@ManyToOne
@JoinColumn
private EntityB entityB;
@ManyToMany
@CollectionTable(uniqueConstraints = { @UniqueConstraint(columnNames = {
"HISTORICAL_ENTITY_ENTITY_A", "HISTORICAL_ENTITY_ENTITY_B",
"HISTORY_ID", }) })
@OrderColumn(name = "POSITION")
private List<EntityC> history;
}
...以及帶有空測試的配置...
package misc;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
public class TestConfiguration {
@Bean
public DataSource dataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:postgresql://localhost:5432/mydb");
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUsername("postgres");
dataSource.setPassword("postgres");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan("pl.xtra_klasa.utils.total.test");
final Map<String, Object> propertyMap = emf.getJpaPropertyMap();
propertyMap.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
propertyMap.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
propertyMap.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "create");
propertyMap.put(org.hibernate.cfg.Environment.DIALECT,
"org.hibernate.dialect.PostgreSQLDialect");
propertyMap.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
return emf;
}
@Bean
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
@Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager tm = new JpaTransactionManager(
entityManagerFactory().getObject());
return tm;
}
}
package misc;
import javax.transaction.Transactional;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
@Transactional
public class MyTest {
@Test
public void test() {
}
}
測試以以下異常結束,我不知道為什么會這樣。
外鍵(FK_85k7tuu55uee70x387oekb6gj:historical_entity_history [historical_entity]))必須與引用的主鍵具有相同的列數(historical_entity [entityb,entitya])
我必須補充一點,一切工作正常,但是我決定切換到org.hibernate.cfg.ImprovedNamingStrategy
並刪除使用@Table(name = "TABLE_NAME")
給表賦予的所有顯式名稱。
我已經為此奮斗了兩個多小時。 我怎樣才能找到問題所在?
僅使用@ElementCollection
注釋屬性history
會導致相同的錯誤。
...
@ElementCollection
private List<EntityC> history;
...
我自己找到了解決方案。 需要明確指定連接列。
@ManyToMany
@CollectionTable(joinColumns = { @JoinColumn(name = "entityA"),
@JoinColumn(name = "entityB") }, uniqueConstraints = { @UniqueConstraint(columnNames = {
"entityA", "entityB", "history" }) })
@OrderColumn(name = "POSITION")
private List<EntityC> history;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.