我有两个对象,它们之间有一对多关系,我实现如下:
@Entity
@Table(name = "details")
public class MainDetails {
@Id
@Column(name = "details_id")
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
// Some other fields here - omitted
@OneToMany(fetch = FetchType.LAZY,
mappedBy = "details",
targetEntity = State.class,
cascade = CascadeType.ALL)
@OrderBy("timestamp DESC")
private List<State> states;
}
第二个:
@Entity
@Table(name = "state")
public class State {
@Id
@Column(name = "state_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "details_id")
private MainDetails details;
// Other fields omitted (including timestamp)
}
我在save()
对象上调用MainDetails
方法。该方法如下所示:
public T save(T obj) { // The T in this case is MainDetails
entityManager.persist(obj);
entityManager.flush();
return obj;
}
但后来我得到了这个例外:
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "details_pkey" Detail: Key (details_id)=(8) already exists.
我的persistence.xml
看起来像这样:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="my-persistence-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- Annotated entity classes -->
<class>com.company.entity.MainDetails</class>
<class>com.company.entity.State</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
</properties>
</persistence-unit>
</persistence>
我的春天语境如下:
@EnableJpaRepositories(basePackages = {"com.company.dao", "com.company.*.dao"})
@EnableTransactionManagement(proxyTargetClass = true)
@Import(BasicConfig.class)
public class DbConfig {
@Value("${db.connection_string}")
private String connectionString;
@Value("${db.user_name}")
private String dbUserName;
@Value("${db.password}")
private String dbPassword;
@Bean
public DataSource dataSource() {
DriverManagerDataSource driver = new DriverManagerDataSource();
driver.setDriverClassName("org.postgresql.Driver");
driver.setUrl(connectionString);
driver.setUsername(dbUserName);
driver.setPassword(dbPassword);
return driver;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(true);
adapter.setGenerateDdl(true);
adapter.setDatabase(Database.POSTGRESQL);
return adapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPersistenceUnitName("my-persistence-unit");
factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
return factoryBean;
}
@Bean
public JpaTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
答案 0 :(得分:5)
好吧,这是我的错(自然而然)我改变了3件事以使其发挥作用:
将这两个类更改为:@GeneratedValue(strategy= GenerationType.TABLE)
(原来我使用的是GenerationType.AUTO
)。
我发现调用save()
的方法也会调用entityManager.flush()
。删除冗余线后,它解决了问题。打败我的原因 - 我希望hibernate在冗余的flush()
调用中什么都不做,但显然这是解决问题的必要条件。