/* * 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.datastore.mongodb.test.index; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.hibernate.HibernateException; import org.hibernate.Transaction; import org.hibernate.annotations.NaturalId; import org.hibernate.ogm.OgmSession; import org.hibernate.ogm.utils.OgmTestCase; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; /** * Test that unique constraints are created on MongoDB for: * <ul> * <li>{@link Id}</li> * <li>{@link NaturalId}</li> * <li>{@link Column} when {@link Column#unique()} is set to {@code true}</li> * <li>{@link Table#uniqueConstraints()} is set</li> * </ul> * * @author Davide D'Alto * @author Guillaume Smet */ public class UniqueConstraintTest extends OgmTestCase { @Rule public ExpectedException thrown = ExpectedException.none(); private EntityWithConstraints entityWithConstraints; @Entity @Table(name = "EntityWithConstraints", uniqueConstraints = @UniqueConstraint(columnNames = { "tableConstraint" })) static class EntityWithConstraints { @Id private String id; @Column(unique = true) private long uniqueColumn; @NaturalId // causes the creation of a unique constraint private String naturalId; private String tableConstraint; private String nonUniqueProperty; public String getId() { return id; } public void setId(String login) { this.id = login; } public long getUniqueColumn() { return uniqueColumn; } public void setUniqueColumn(long uniqueColumn) { this.uniqueColumn = uniqueColumn; } public String getNaturalId() { return naturalId; } public void setNaturalId(String naturalId) { this.naturalId = naturalId; } public String getTableConstraint() { return tableConstraint; } public void setTableConstraint(String constraint) { this.tableConstraint = constraint; } public String getNonUniqueProperty() { return nonUniqueProperty; } public void setNonUniqueProperty(String nonUniqueProperty) { this.nonUniqueProperty = nonUniqueProperty; } } @Before public void setup() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); entityWithConstraints = new EntityWithConstraints(); entityWithConstraints.setId( "johndoe" ); entityWithConstraints.setUniqueColumn( 12345678 ); entityWithConstraints.setNaturalId( "John Doe" ); entityWithConstraints.setTableConstraint( "unique" ); entityWithConstraints.setNonUniqueProperty( "no constraints here" ); session.save( entityWithConstraints ); tx.commit(); session.close(); } @After public void cleanup() { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); session.delete( entityWithConstraints ); tx.commit(); session.close(); } @Test public void shouldThrowExceptionForDuplicatedNaturalId() throws Throwable { thrown.expect( HibernateException.class ); thrown.expectMessage( "OGM001230" ); thrown.expectMessage( "UK_r4dom13cd9fcnuy5i2ku9mp07" ); try { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); EntityWithConstraints duplicated = new EntityWithConstraints(); duplicated.setId( "login1" ); duplicated.setUniqueColumn( 1l ); duplicated.setNaturalId( entityWithConstraints.getNaturalId() ); duplicated.setTableConstraint( "tableConstraint1" ); session.save( duplicated ); tx.commit(); session.close(); } catch (Exception e) { throw extract( HibernateException.class, e ); } } @Test public void shouldThrowExceptionForDuplicatedUniqueColumn() throws Throwable { thrown.expect( HibernateException.class ); thrown.expectMessage( "OGM001230" ); thrown.expectMessage( "UK_rqop0uacscxoslvnfnki9rds4" ); try { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); EntityWithConstraints duplicated = new EntityWithConstraints(); duplicated.setId( "login2" ); duplicated.setUniqueColumn( entityWithConstraints.getUniqueColumn() ); duplicated.setNaturalId( "naturalId2" ); duplicated.setTableConstraint( "tableConstraint2" ); session.save( duplicated ); tx.commit(); session.close(); } catch (Exception e) { throw extract( HibernateException.class, e ); } } @Test public void shouldThrowExceptionForDuplicatedTableUniqueConstraintColumn() throws Throwable { thrown.expect( HibernateException.class ); thrown.expectMessage( "OGM001230" ); thrown.expectMessage( "UKhno5buc5dcefobq7wx2rm5oqy" ); try { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); EntityWithConstraints duplicated = new EntityWithConstraints(); duplicated.setId( "login3" ); duplicated.setUniqueColumn( 3l ); duplicated.setNaturalId( "naturalId3" ); duplicated.setTableConstraint( entityWithConstraints.getTableConstraint() ); session.save( duplicated ); tx.commit(); session.close(); } catch (Exception e) { throw extract( HibernateException.class, e ); } } @Test // Not expecting any exception public void shouldNotCreateConstraintForNonUniqueProperty() throws Exception { OgmSession session = openSession(); Transaction tx = session.beginTransaction(); EntityWithConstraints duplicated = new EntityWithConstraints(); duplicated.setId( "login4" ); duplicated.setUniqueColumn( 4l ); duplicated.setNaturalId( "naturalId4" ); duplicated.setTableConstraint( "tableConstraint4" ); duplicated.setNonUniqueProperty( entityWithConstraints.getNonUniqueProperty() ); session.save( duplicated ); tx.commit(); session.close(); } private <T extends Throwable> T extract(Class<T> class1, Exception e) throws Throwable { Throwable cause = e; while ( cause != null ) { if ( cause.getClass().equals( class1 ) ) { break; } cause = cause.getCause(); } throw cause; } @Override public Class<?>[] getAnnotatedClasses() { return new Class<?>[] { EntityWithConstraints.class }; } }