Avi*_*Avi 1 java spring hibernate
我有两个对象,它们之间具有一对多的关系,实现如下:
@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;
}
Run Code Online (Sandbox Code Playgroud)
第二个:
@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)
}
Run Code Online (Sandbox Code Playgroud)
我save()在MainDetails对象上调用一个方法。该方法如下所示:
public T save(T obj) { // The T in this case is MainDetails
entityManager.persist(obj);
entityManager.flush();
return obj;
}
Run Code Online (Sandbox Code Playgroud)
但是然后我得到这个异常:
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "details_pkey" Detail: Key (details_id)=(8) already exists.
Run Code Online (Sandbox Code Playgroud)
我的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>
Run Code Online (Sandbox Code Playgroud)
我的春季背景看起来像这样:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
好的,那是我的错误(自然地),为了使它起作用,我更改了3件事:
将两个类都更改为:(@GeneratedValue(strategy= GenerationType.TABLE)最初使用GenerationType.AUTO)。
我发现调用的方法save()也会调用entityManager.flush()。删除冗余线路后,它解决了问题。让我感到沮丧-我希望休眠状态在冗余flush()呼叫上什么也不做,但是显然这是解决问题的必要条件。