Skip to content

Instantly share code, notes, and snippets.

@jwgmeligmeyling
Created May 18, 2016 22:19
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jwgmeligmeyling/e409362ad3f3923a72a5efb42f92ff74 to your computer and use it in GitHub Desktop.
Save jwgmeligmeyling/e409362ad3f3923a72a5efb42f92ff74 to your computer and use it in GitHub Desktop.
Persisting recursive relationships with Hibernate

Persist Recursive relationships with Hibernate

Example on how to persist recursive relationships with Hibernate, using in this case a UUIDGenerator.

package org.hibernate.test;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.persist.PersistService;
import com.google.inject.persist.jpa.JpaPersistModule;
public class DatabaseTestModule extends AbstractModule {
@Override
protected void configure() {
install(new JpaPersistModule("default"));
bind(JPAInitializer.class).asEagerSingleton();
}
@Singleton
public static class JPAInitializer {
@Inject
public JPAInitializer(final PersistService service) {
service.start();
}
}
}
package org.hibernate.test;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;
@Data
@Entity
@Table(name = "node")
@ToString(exclude = {"parent"})
@EqualsAndHashCode(of = {"uuid"})
public class Node {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Column(name = "uuid")
private String uuid;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "parent", referencedColumnName = "uuid")
private Node parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Node> children;
}
<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="default" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:./recursion-test" />
<property name="hibernate.connection.user" value="admin" />
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hibernate.test</groupId>
<artifactId>test-recursion</artifactId>
<version>1.0-SNAPSHOT</version>
<description>Example to show how to persist recursive relationships with Hibernate.</description>
<developers>
<developer>
<name>Jan-Willem Gmelig Meyling</name>
<email>jan-willem@youngmediaexperts.nl</email>
</developer>
</developers>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<hibernate.version>5.1.0.Final</hibernate.version>
<guice.version>4.0</guice.version>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.191</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-persist</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jukito</groupId>
<artifactId>jukito</artifactId>
<version>1.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package org.hibernate.test;
import com.google.inject.persist.Transactional;
import org.jukito.JukitoRunner;
import org.jukito.UseModules;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.iterableWithSize;
@RunWith(JukitoRunner.class)
@UseModules(DatabaseTestModule.class)
public class RecursiveDependencyTest {
@Inject EntityManager entityManager;
@Test
@Transactional
public void testBiDirectionalPersistenceWithUUIDGenerator() throws Exception {
Node parent = new Node();
Node child = new Node();
// Add child to parents children
List<Node> parentsChildren = new ArrayList<>();
parentsChildren.add(child);
parent.setChildren(parentsChildren);
// Set back reference as well
child.setParent(parent);
entityManager.persist(parent);
assertThat(parent.getChildren(), iterableWithSize(1));
}
}
@GabrielBB
Copy link

It was useful. Thanks

@trochepablo
Copy link

great!!

@ImSeenOne
Copy link

How could I do it if I just need it to be OneToOne

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment