我有以下实体。
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")
给表格的所有显式名称。
我现在已经挣扎了几个多小时了。我怎样才能找到问题所在?
仅使用history
注释属性@ElementCollection
会导致同样的错误。
...
@ElementCollection
private List<EntityC> history;
...
答案 0 :(得分:0)
我自己找到了解决方案。需要明确指定连接列。
@ManyToMany
@CollectionTable(joinColumns = { @JoinColumn(name = "entityA"),
@JoinColumn(name = "entityB") }, uniqueConstraints = { @UniqueConstraint(columnNames = {
"entityA", "entityB", "history" }) })
@OrderColumn(name = "POSITION")
private List<EntityC> history;