I have two objects with one-to-many relationship between them that I implemented as follows:
@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;
}
And the second one:
@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)
}
I call a save() method on the MainDetails object. The method looks like this:
public T save(T obj) { // The T in this case is MainDetails
entityManager.persist(obj);
entityManager.flush();
return obj;
}
But then I get this exception:
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "details_pkey" Detail: Key (details_id)=(8) already exists.
My persistence.xml looks like this:
<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>
My spring context looks like this:
@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;
}
}
detailstable and retry. It already has ID 8 in it. And is the obj inentityManager.persist(obj);already has id field populated. Is so call merge method.serialcolumn type for the id.