Skip to content

Commit

Permalink
OGM-1288 Test recursive associations
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideD authored and gsmet committed Jul 7, 2017
1 parent 6b4bedd commit 94d7db2
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 0 deletions.
@@ -0,0 +1,125 @@
/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.ogm.backendtck.associations.recursive;

import static org.fest.assertions.Assertions.assertThat;

import java.util.concurrent.atomic.AtomicInteger;

import org.hibernate.Transaction;
import org.hibernate.ogm.OgmSession;
import org.hibernate.ogm.utils.OgmTestCase;
import org.hibernate.ogm.utils.TestForIssue;
import org.junit.Before;
import org.junit.Test;

/**
* Creates a tree where each node has a certain number of children and then executes some CRUD operation on it.
*
* @author Davide D'Alto
*/
@TestForIssue(jiraKey = { "OGM-1284", "OGM-1292" })
public class RecursiveAssociationsTest extends OgmTestCase {

int DEPTH = 3;
int NUM_CHILDREN = 3;

@Before
public void before() {
createTree();
}

/*
* Simple tree generation.
* The tree will look something like (depth 2, children 2):
*
* -- (NODE: 6)
* -- (NODE: 4) |
* | -- (NODE: 5)
* (ROOT: 0) --
* | -- (NODE: 3)
* -- (NODE: 1) |
* -- (LEAF: 2)
*/
private void createTree() {
try ( OgmSession session = openSession() ) {
AtomicInteger index = new AtomicInteger( 0 );
Transaction tx = session.beginTransaction();
TreeNode root = new TreeNode( name( index.get() ) );
session.persist( root );
createChildren( session, root, 1, index );
tx.commit();
}
}

private void createChildren(OgmSession session, TreeNode parent, int currentDepth, AtomicInteger index) {
for ( int i = 0; i < NUM_CHILDREN; i++ ) {
index.incrementAndGet();
TreeNode child = createNode( parent, index.get() );
session.persist( child );
if ( currentDepth < DEPTH ) {
createChildren( session, child, currentDepth + 1, index );
}
}
}

private String name(int index) {
return "NODE: " + index;
}

private TreeNode createNode(TreeNode parent, int middle) {
TreeNode child = new TreeNode( name( middle ) );
parent.getChildren().add( child );
child.setParent( parent );
return child;
}

@Test
public void test() throws Exception {
try ( OgmSession session = openSession() ) {
Transaction tx = session.beginTransaction();
TreeNode root = session.load( TreeNode.class, name( 0 ) );
assertThat( root.getChildren() ).hasSize( NUM_CHILDREN );

TreeNode node = session.load( TreeNode.class, name( 1 ) );
assertThat( node.getChildren() ).hasSize( NUM_CHILDREN );

TreeNode leaf = session.load( TreeNode.class, name( 3 ) );
assertThat( leaf.getChildren() ).isEmpty();

tx.commit();
}

deleteNode( 2 );

try ( OgmSession session = openSession() ) {
Transaction tx = session.beginTransaction();
TreeNode root = session.load( TreeNode.class, name( 0 ) );

assertThat( root ).isNotNull();
assertThat( root.getChildren() ).hasSize( NUM_CHILDREN );

TreeNode node = session.load( TreeNode.class, name( 1 ) );
assertThat( node.getChildren() ).hasSize( NUM_CHILDREN - 1 );

tx.commit();
}
}

private void deleteNode(int nodeId) {
try ( OgmSession session = openSession() ) {
Transaction tx = session.beginTransaction();
session.delete( session.load( TreeNode.class, name( nodeId ) ) );
tx.commit();
}
}

@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[]{ TreeNode.class };
}
}
@@ -0,0 +1,100 @@
/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.ogm.backendtck.associations.recursive;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

/**
* @author Davide D'Alto
*/
@Entity
public class TreeNode {

@Id
private String name;

@ManyToOne
private TreeNode parent;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TreeNode> children = new ArrayList<TreeNode>( 3 );

public TreeNode() {
}

public TreeNode(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public TreeNode getParent() {
return parent;
}

public void setParent(TreeNode parent) {
this.parent = parent;
}

public List<TreeNode> getChildren() {
return children;
}

public void setChildren(List<TreeNode> children) {
this.children = children;
}

@Override
public String toString() {
return name;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
return result;
}

@Override
public boolean equals(Object obj) {
if ( this == obj ) {
return true;
}
if ( obj == null ) {
return false;
}
if ( getClass() != obj.getClass() ) {
return false;
}
TreeNode other = (TreeNode) obj;
if ( name == null ) {
if ( other.name != null ) {
return false;
}
}
else if ( !name.equals( other.name ) ) {
return false;
}
return true;
}
}

0 comments on commit 94d7db2

Please sign in to comment.