I'm trying to build this simple project but I keep getting the same error. Can anybody help figure this out?
HibernateTest.java
public class HibernateTest
{
public static void main(String[] args)
{
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
Query query = session.getNamedQuery("findById");
List<?> list = query.list();
if (!list.isEmpty())
{ UserDetails userD = (UserDetails) list.get(0);
System.out.println(userD); }
}
}
UserDetails.java
package com;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
#Entity
#Table (name="UserDetails")
#NamedQuery(
name = "findById",
query = "SELECT x FROM UserDetails x WHERE x.id = '3'")
public class UserDetails
{
#Id
#Column(name="UserID")
private int id;
#Column(name="UserName")
private String name;
public void setId(int id)
{ this.id = id; }
public int getId()
{ return id; }
public void setName(String name)
{ this.name = name; }
public String getName()
{ return name; }
}
I'm not exactly sure what's wrong because I have the same query running in a different project and it works fine.
I got the same issue and i have resolved the issue by adding the following in applicationContext.xml.
<property name="annotatedClasses">
<list>
<value>com.Employee</value>
</list>
</property>
If you are using XML configuration, you can define a named query with the <query> tag. For example:
<query name = "findById">
<![CDATA[SELECT x FROM UserDetails x WHERE x.id = '3']]>
</query>
The <query> tag is on the same level as the <class> tag, as a child of the <hibernate-mapping> tag.
While this will not answer your immediate problem, if you are using Hibernate, and JPA annotations, why not using EntityManager instead of Hibernate session and stuff ?
With a Persistence Unit (as well as persistence.xml in your META-INF folder), you would do that:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("persistenceUnit");
EntityManager em = emf.createEntityManager();
Query query = em.createNamedQuery("findById");
Or better:
TypedQuery<UserDetails> query = em.createNamedQuery("findById", UserDetails.class);
The method are roughly the same (after all, JPA was made of Hibernate).
Related
I am trying to understand the principles of ManyToMany relations in Hibernate. I've created a small test project and the question is:
I want "Managers" to be saving in db when the "User" is saving. So Manager entity is dependent on User.
When I am saving user1 - everything is fine. I am getting user1 and manager1 and manager3 saved to db. But on the next row where I am trying to save user2 to db I am getting an Exception:
Converting org.hibernate.PersistentObjectException to JPA PersistenceException : detached entity passed to persist: ua.testing.entities.Manager
I think the problem is because I am trying to save user2 which contains manager1, which was saved in db in previous row.
But how can I avoid this problem and make everything work?
User entity:
package ua.testing.entities;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany(cascade = CascadeType.ALL)
private List<Manager> managerList = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<Manager> getManagerList() {
return managerList;
}
public void setManagerList(List<Manager> managerList) {
this.managerList = managerList;
}
}
Manager entity:
package ua.testing.entities;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "manager")
public class Manager {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany(mappedBy = "managerList")
private List<User> userList = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
Main method:
package ua.testing;
import ua.testing.dao.UserDao;
import ua.testing.entities.*;
public class App
{
public static void main( String[] args )
{
User user1 = new User();
User user2 = new User();
User user3 = new User();
Manager manager1 = new Manager();
Manager manager2 = new Manager();
Manager manager3 = new Manager();
manager1.getUserList().add(user1);
manager1.getUserList().add(user2);
manager2.getUserList().add(user1);
manager2.getUserList().add(user3);
manager3.getUserList().add(user2);
manager3.getUserList().add(user3);
user1.getManagerList().add(manager1);
user1.getManagerList().add(manager3);
user2.getManagerList().add(manager1);
user2.getManagerList().add(manager2);
user3.getManagerList().add(manager2);
user3.getManagerList().add(manager3);
UserDao userDao = new UserDao();
userDao.persist(user1);
userDao.persist(user2); // EXCEPTION HERE
}
}
Exception I am getting:
Exception in thread "main" jakarta.persistence.PersistenceException: Converting `org.hibernate.PersistentObjectException` to JPA `PersistenceException` : detached entity passed to persist: ua.testing.entities.Manager
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:165)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:175)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:182)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:783)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:725)
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:299)
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:289)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:511)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:432)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:545)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:475)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:435)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:474)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:184)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:129)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:53)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:735)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:719)
at ua.testing.dao.UserDao.persist(UserDao.java:13)
at ua.testing.App.main(App.java:34)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: ua.testing.entities.Manager
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:121)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:777)
... 23 more
I ve created a table in Postgres and do a relation in java code :
#Getter
#Setter
#Entity
#Table(name = "resources")
public class Resource {
#Id
#Column(name = "raport_id")
private BigDecimal raportId;
#Column(name = "reference_id")
private String referenceId;
}
Also I created a repository
public class ResourcesRepository {
#PersistenceContext
private EntityManager entityManager;
public void persist(BigDecimal raportId, String referenceId, String type) {
Resource resource = new Resource();
resource.setRaportSysId(raportId);
resource.setReferenceId(referenceId);
entityManager.persist(raport);
}
public void updateRaportId(BigDecimal raportId) {
entityManager.createQuery("UPDATE Resource r set r.raportId = :raportId ")
.setParameter("raportId", raportId)
.executeUpdate();
}
}
I am passing the parameter raportId in dofferent location invoking the query like this:
ResourcesRepository.updateRaportId(raport.getId());
I do not have any errors but the table is not populated. Wonder what I am doing wrong? Should I use Insert INTO instead of update?
make sure you commit your transaction after update/persist
Currently we are doing a performance review and improvement of the DB CRUD function of the application and one of the reviews was using Hikari connection pool and a later version of Hibernate and Hibernate-HikariCP for our tests.
We are running this by upgrading the Hibernate version from 5.2.10 to 5.2.16, with Hikari at version 3.1.0. This entire exercise was tested with Tomcat 8 and MSSQL 2016.
For simplicity purposes, we tested on one simple search with one search condition using the entity User.
Hibernate XML Configuration:
<hibernate-configuration>
<session-factory>
<property name = "hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="show_sql">true</property>
<!-- Hikari specific properties -->
<property name="hibernate.connection.provider_class">com.zaxxer.hikari.hibernate.HikariConnectionProvider</property>
<property name="hikari.maximumPoolSize">30</property>
<property name="hikari.idleTimeout">300000</property>
<property name="hikari.maxLifetime">1800000</property>
<!-- Database connection properties -->
<property name="hibernate.hikari.dataSourceClassName">com.microsoft.sqlserver.jdbc.SQLServerDataSource</property>
<property name="hibernate.connection.url">jdbc:sqlserver://192.168.0.102:1433;databaseName=migration1;user=sun;password=p#ssw0rd;</property>
<property name = "hibernate.connection.username">sun</property>
<property name = "hibernate.connection.password">p#ssw0rd</property>
<mapping class="com.hib.model.Outlet"/>
<mapping class="com.hib.model.Receipt"/>
<mapping class="com.hib.model.Cashier"/>
<mapping class="com.hib.model.Category"/>
<mapping class="com.hib.model.Item"/>
<mapping class="com.hib.model.PayMethodName"/>
<mapping class="com.hib.model.Pos"/>
<mapping class="com.hib.model.Purchase"/>
<mapping class="com.hib.model.User"/>
</session-factory>
</hibernate-configuration>
The HibernateUtil class is quite simple, currently as:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
sessionFactory = new Configuration().configure().buildSessionFactory(builder.build());
} catch (Throwable th) {
System.err.println("Initial SessionFactory creation failed " + th);
throw new ExceptionInInitializerError(th);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
The User Entity, annotated, excluding the getter / setters:
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
#Entity
#Table(name = "User")
#XmlRootElement
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#Column(name = "id")
#NotNull
#GeneratedValue(generator="`id`")
#GenericGenerator(name="`id`", strategy = "increment")
private Integer id;
#NotNull
#Column(name = "FullName")
private String fullName;
#Column(name = "NickName")
private String nickName;
#Column(name = "Tel")
private String tel;
#Column(name = "Rank")
private String rank;
#NotNull
#Column(name = "Email")
private String email;
#NotNull
#Column(name = "Password")
private String password;
#Lob
#Column(name = "PhotoUpload")
private String photoUpload;
#Version
#Column(name = "CreateDate")
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
private Date createDate;
#Version
#Column(name = "EditDate")
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
private Date editDate;
#Column(name = "CreateBy")
private String createBy;
#Column(name = "ActiveInd")
private String activeInd;
#Column(name = "LastLogin")
#Temporal(TemporalType.TIMESTAMP)
private Date lastLogin;
#Column(name = "tenant_id")
private String tenantId;
#NotNull
#Column(name = "group_id")
private String groupId;
public User() {
}
public User(Integer id, String fullName,String nickName,String tel,String rank,String email,String password,String photoUpload,Date createDate,Date editDate,String createBy,String activeInd,Date lastLogin, String tenantId, String groupId) {
this.id = id;
this.fullName = fullName;
this.nickName = nickName;
this.tel =tel;
this.rank=rank;
this.email =email;
this.password = password;
this.photoUpload = photoUpload;
this.createDate =createDate;
this.editDate =editDate;
this.createBy =createBy;
this.activeInd = activeInd;
this.lastLogin=lastLogin;
this.tenantId= tenantId;
this.groupId =groupId;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.example.dao.User[ id=" + id + " ]";
}
The function of searching the particular Users is in this method of the User Service class:
#Override
public List<User> getUserById(Integer id) {
List<User> result = null;
Session session = getSession();
try {
Criteria criteria = getSession().createCriteria(User.class);
Criteria criteria = getSession().(User.class);
criteria.add(Restrictions.eq("id", id));
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
result = query.getResultList();
}catch (HibernateException e){
userLogger.error("Error found: " + e);
}finally {
if (session != null)
session.close();
}
return result;
}
When tested, if the original C3P0 connection pool is used, the search function above will return the expected result of the matching record corresponding to the Id number passed in (numeric value).
However, when switched to HikariCP, the result returns null. However, if we write a NativeQuery instead of Criteria, it does not get affected.
Subsequently, we tried three alternatives to see if it works but with different errors:
Option 1: - returns an IllegalArgumentException, entity User not mapped
TypedQuery<User> query = session.createQuery("select u from "+User.class.getSimpleName()+" u",User.class) ;
result = query.getResultList();
Option 2: - returns an IllegalArgumentException, not an entity User.
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);
cq.select(root);
Query<User> q = session.createQuery(cq);
result = q.getResultList();
Option 3 - returns a mapping exception, unknown entity User:
String sql = "SELECT * FROM USER_LOG WHERE id = :number_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(User.class);
query.setParameter("number_id", id);
result = query.list();
As HikariCP has done a lot of improvements for the other Native Queries, we felt it is better if we can still keep on using that CP in favor of the C3P0 pool. However, we are still stuck as in unsure to which approach in the Service class method is best used.
We appreciate any advise on help on this. Thanks.
I am using JPA createquery API to fetch the data.
Here is my query data
#PersistenceContext
EntityManager entityManager;
#Override
public List<String> fetchAllReleaseNumbers() {
Query query = entityManager.createQuery("SELECT release FROM ReleaseModel", String.class);
return query.getResultList();
}
and here is my pojo class.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "dbname.tablenamefromDB")
public class ReleaseModel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "dbcolumnname", unique = true, nullable = false)
private String release;
#Column(name = "dbcolumnname")
private String releaseDesc;
#Column(name = "dbcolumnname")
private Integer releaseStatus;
#Column(name = "dbcolumnname")
private Integer releaseMode;
public String getRelease() {
return release;
}
public void setRelease(String release) {
this.release = release;
}
public String getReleaseDesc() {
return releaseDesc;
}
public void setReleaseDesc(String releaseDesc) {
this.releaseDesc = releaseDesc;
}
public Integer getReleaseStatus() {
return releaseStatus;
}
public void setReleaseStatus(Integer releaseStatus) {
this.releaseStatus = releaseStatus;
}
public Integer getReleaseMode() {
return releaseMode;
}
public void setReleaseMode(Integer releaseMode) {
this.releaseMode = releaseMode;
}
}
Though the table exists in db its throwing not exist.Any ideas where I made mistake.
I tried whether any aliases can be given to the table name.
I am using pojo class name only for createQuery.
TIA.
You should specify a schema name by this way
#Table(schema = "dbname", name = "tablenamefromDB")
You have an incorrect mapping:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "dbcolumnname", unique = true, nullable = false)
private String release;
I think String can't be auto generated.
Also all your columns have dbcolumnname name.
The issue was that the schema was not specified in the entity class or the user did not login using proxy. If the user login using a proxy access i.e. userName[schemaName] they do not need to specify schema in the entity class. But if the user login using just the userName, they need to specify the schema in the entity. This is to specify where the table can be found in the database.
I have a question regarding circular relationships in JPA, and here in particular with Eclipselink JPA implementation. Sorry if the question is a bit long, but I try to be as precise as possible.
Let's take the simple example of Department and Employee where a Department has a one-to-many "employees" relationship (and hence the reverse many-to-one "department" relationship from Employee to Department). Now let's add a one-to-one relationship "manager" from Department towards Employee (one of the Employees of the Department is the manager of that same Department). That introduces a circular relationship between the two entities and both tables will have a foreign key referencing the other table.
I would like to be able to do all the inserts without getting a Foreign key constraint violation. So, my idea was to first insert all employees (without setting the department relationship), then insert the Department (with its manager being set), and eventually update all the employees to set their Department.
I know that I could use flush() to force the order of insert execution but I was told that it should be avoided and hence wondering if there is a way to tell JPA/Eclipselink that Department should be inserted first, then Employee.
In Eclipselink, I did try to add Employee as a constraint dependency of the classdescriptor of the Department class but it still gives error randomly.
Here is a code example illustrating this (the issue occurs randomly):
Department class:
package my.jpa.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Persistence;
/**
* Entity implementation class for Entity: Department
*
*/
#Entity
public class Department implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(fetch = FetchType.EAGER)
private List<Employee> employees;
#OneToOne
#JoinColumn(name = "manager", nullable = false)
private Employee manager;
private static final long serialVersionUID = 1L;
public Department() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jpa");
EntityManager em = emf.createEntityManager();
Department d = new Department();
Employee manager = new Employee();
manager.setLastName("Doe");
d.setManager(manager);
Employee e1 = new Employee();
e1.setLastName("Doe");
Employee e2 = new Employee();
e2.setLastName("Smith");
em.getTransaction().begin();
em.persist(d);
manager.setDepartment(d);
e1.setDepartment(d);
e2.setDepartment(d);
em.persist(e1);
em.persist(e2);
em.persist(manager);
em.persist(d);
manager.setDepartment(d);
e1.setDepartment(d);
e2.setDepartment(d);
em.merge(manager);
em.merge(e1);
em.merge(e2);
em.getTransaction().commit();
em.clear();
Department fetchedDepartment = em.find(Department.class, d.getId());
System.err.println(fetchedDepartment.getManager().getLastName());
System.err.println(new ArrayList<Employee>(fetchedDepartment.getEmployees()));
}
public Employee getManager() {
return manager;
}
public void setManager(Employee manager) {
this.manager = manager;
}
}
Employee class:
package my.jpa.test;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
/**
* Entity implementation class for Entity: Employee
*
*/
#Entity
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String lastName;
#ManyToOne
private Department department;
#OneToOne(mappedBy = "manager")
private Department managedDepartment;
public Employee() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Department getManagedDepartment() {
return managedDepartment;
}
public void setManagedDepartment(Department managedDepartment) {
this.managedDepartment = managedDepartment;
}
#Override
public String toString() {
return "Employee " + getLastName();
}
}
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="test-jpa">
<class>my.jpa.test.Department</class>
<class>my.jpa.test.Employee</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
Maven dependencies:
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.172</version>
</dependency>
</dependencies>
IMHO with this model you don't really have the choice.
Insert department (without manager)
insert employee (with departments)
flush
update department manager.
Deleting will probably be a mess too
Otherwise you could create an association table between department and employee to hold an isManager attribute.
Or put this last in employee table (not very normalized but well...)
From a general point of view it seems that circular reference are not advised in a relational model :
In SQL, is it OK for two tables to refer to each other?
I think that if you configure the departament column in Employee to allow null and set cascades correctly it can solve the problem. And please, do not use flush