/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.util.persistence;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.opencastproject.util.data.Option.none;
import static org.opencastproject.util.persistence.PersistenceEnvs.testPersistenceEnv;
import org.opencastproject.util.data.Effect;
import org.opencastproject.util.data.Either;
import org.opencastproject.util.data.Function;
import org.opencastproject.util.data.Option;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import javax.persistence.EntityManager;
public class PersistenceUtilTest {
private PersistenceEnv penv;
@Before
public void before() {
penv = testPersistenceEnv("test");
}
@After
public void after() {
penv.close();
}
@Test
public void testPersistAndFind() {
final long id = penv.tx(Queries.persist(TestDto.create("key", "value"))).getId();
assertEquals("value", penv.tx(Queries.find(TestDto.class, id)).get().getValue());
}
@Test
public void testPersistOrUpdateUpdate() {
assertTrue(penv.tx(TestDto.findAll).isEmpty());
final TestDto dto = penv.tx(Queries.persist(TestDto.create("key", "value")));
assertEquals("value", penv.tx(Queries.find(TestDto.class, dto.getId())).get().getValue());
dto.setValue("new-value");
penv.tx(Queries.persistOrUpdate(dto));
assertEquals("new-value", penv.tx(Queries.find(TestDto.class, dto.getId())).get().getValue());
}
@Test
public void testPersistOrUpdatePersist() {
assertTrue(penv.tx(TestDto.findAll).isEmpty());
final TestDto dto = penv.tx(Queries.persistOrUpdate(TestDto.create("key", "value")));
assertEquals("value", penv.tx(Queries.find(TestDto.class, dto.getId())).get().getValue());
dto.setValue("new-value");
penv.tx(Queries.persistOrUpdate(dto));
assertEquals("new-value", penv.tx(Queries.find(TestDto.class, dto.getId())).get().getValue());
}
@Test
public void testCloseEntityManager() {
penv.tx(new Function<EntityManager, Object>() {
@Override public Object apply(EntityManager entityManager) {
// this should not throw an exception in penv.tx()
entityManager.close();
return null;
}
});
}
@Test(expected = RuntimeException.class)
public void testException() {
penv.tx(new Function<EntityManager, Object>() {
@Override public Object apply(EntityManager entityManager) {
throw new RuntimeException("error");
}
});
}
@Test(expected = IllegalStateException.class)
public void testExceptionTransformation1() {
penv.tx().rethrow(new Function<Exception, Exception>() {
@Override public Exception apply(Exception e) {
return new IllegalStateException(e);
}
}).apply(new Function<EntityManager, Object>() {
@Override public Object apply(EntityManager entityManager) {
throw new RuntimeException("error");
}
});
}
@Test
public void testExceptionTransformation2() {
final boolean[] exception = {false};
penv.<Void>tx().handle(new Effect<Exception>() {
@Override public void run(Exception e) {
exception[0] = true;
}
}).apply(new Effect<EntityManager>() {
@Override protected void run(EntityManager entityManager) {
throw new RuntimeException("error");
}
});
assertTrue(exception[0]);
}
@Test
public void testExceptionTransformation3() {
final Option<String> r = penv.<Option<String>>tx().handle(new Function<Exception, Option<String>>() {
@Override public Option<String> apply(Exception e) {
return none();
}
}).apply(new Function<EntityManager, Option<String>>() {
@Override public Option<String> apply(EntityManager entityManager) {
throw new RuntimeException("error");
}
});
assertTrue(r.isNone());
}
@Test
public void testExceptionTransformation4() {
final Either<String, Integer> r = penv.<Integer>tx().either(new Function<Exception, String>() {
@Override public String apply(Exception e) {
return "error";
}
}).apply(new Function<EntityManager, Integer>() {
@Override public Integer apply(EntityManager entityManager) {
throw new RuntimeException("error");
}
});
assertEquals("error", r.left().value());
}
@Test
public void testTransactionPropagation() {
long id = penv.tx(new Function<EntityManager, Long>() {
@Override public Long apply(EntityManager em) {
final TestDto dto = TestDto.create("key", "A");
em.persist(dto);
// nested transaction. if transaction propagation would fail a duplicate key exception would be thrown
return save(dto);
}
});
assertEquals("dto value", "B", penv.tx(Queries.find(TestDto.class, id)).get().getValue());
}
private long save(TestDto dto) {
dto.setValue("B");
return penv.tx(Queries.persist(dto)).getId();
}
}