/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
*
* 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.jboss.errai.jpa.test.client;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import org.jboss.errai.ioc.client.Container;
import org.jboss.errai.ioc.client.container.IOC;
import org.jboss.errai.jpa.client.local.ErraiEntityManager;
import org.jboss.errai.jpa.client.shared.GlobalEntityListener;
import org.jboss.errai.jpa.test.client.res.JpaClientTestCase;
import org.jboss.errai.jpa.test.entity.Album;
import org.jboss.errai.jpa.test.entity.Artist;
import org.jboss.errai.jpa.test.entity.CallbackLogEntry;
import org.jboss.errai.jpa.test.entity.TestingGlobalEntityListener;
import org.jboss.errai.jpa.test.entity.Zentity;
/**
* Tests the client-side {@link GlobalEntityListener} annotation.
*
* @author Jonathan Fuerth <jfuerth@gmail.com>
*/
public class GlobalEntityListenerTest extends JpaClientTestCase {
@Override
public String getModuleName() {
return "org.jboss.errai.jpa.test.JpaTest";
}
protected EntityManager getEntityManager() {
final JpaTestClient testClient = JpaTestClient.INSTANCE;
assertNotNull(testClient);
assertNotNull(testClient.entityManager);
((ErraiEntityManager) JpaTestClient.INSTANCE.entityManager).removeAll();
return JpaTestClient.INSTANCE.entityManager;
}
@Override
protected void gwtSetUp() throws Exception {
super.gwtSetUp();
TestingGlobalEntityListener.CALLBACK_LOG.clear();
// We need to bootstrap the IoC container manually because GWTTestCase
// doesn't call onModuleLoad() for us.
new Container().bootstrapContainer();
}
@Override
protected void gwtTearDown() throws Exception {
Container.reset();
IOC.reset();
}
public void testStoreAndFetchAlbumLifecycle() throws Exception {
assertTrue(TestingGlobalEntityListener.CALLBACK_LOG.isEmpty());
// make it
final Album album = new Album();
album.setArtist(null);
album.setName("Abbey Road");
album.setReleaseDate(new Date(-8366400000L));
// store it
final EntityManager em = getEntityManager();
em.persist(album);
em.flush();
em.detach(album);
final List<CallbackLogEntry> expectedLifecycle = new ArrayList<>();
expectedLifecycle.add(new CallbackLogEntry(album, PrePersist.class));
expectedLifecycle.add(new CallbackLogEntry(album, PostPersist.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// fetch a fresh copy
final Album fetchedAlbum = em.find(Album.class, album.getId());
expectedLifecycle.add(new CallbackLogEntry(fetchedAlbum, PostLoad.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// fetch again; expect no more PostLoad notifications
final Album fetchedAlbum2 = em.find(Album.class, album.getId());
assertSame(fetchedAlbum, fetchedAlbum2);
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
}
public void testMultipleEntityTypesLifecycle() throws Exception {
assertTrue(TestingGlobalEntityListener.CALLBACK_LOG.isEmpty());
// make them
final Zentity zentity = new Zentity();
final Album album = new Album();
album.setArtist(null);
album.setName("Abbey Road");
album.setReleaseDate(new Date(-8366400000L));
// store them
final EntityManager em = getEntityManager();
em.persist(zentity);
em.persist(album);
em.flush();
em.clear();
final List<CallbackLogEntry> expectedLifecycle = new ArrayList<>();
expectedLifecycle.add(new CallbackLogEntry(zentity, PrePersist.class));
expectedLifecycle.add(new CallbackLogEntry(zentity, PostPersist.class));
expectedLifecycle.add(new CallbackLogEntry(album, PrePersist.class));
expectedLifecycle.add(new CallbackLogEntry(album, PostPersist.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// fetch a fresh copy
final Album fetchedAlbum = em.find(Album.class, album.getId());
expectedLifecycle.add(new CallbackLogEntry(fetchedAlbum, PostLoad.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// fetch again; expect no more PostLoad notifications
final Album fetchedAlbum2 = em.find(Album.class, album.getId());
assertSame(fetchedAlbum, fetchedAlbum2);
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
}
public void testRemoveEntityLifecycle() throws Exception {
assertTrue(TestingGlobalEntityListener.CALLBACK_LOG.isEmpty());
// make it
final Album album = new Album();
album.setArtist(null);
album.setName("Abbey Road");
album.setReleaseDate(new Date(-8366400000L));
// store it
final EntityManager em = getEntityManager();
em.persist(album);
em.flush();
em.detach(album);
final List<CallbackLogEntry> expectedLifecycle = new ArrayList<>();
expectedLifecycle.add(new CallbackLogEntry(album, PrePersist.class));
expectedLifecycle.add(new CallbackLogEntry(album, PostPersist.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// fetch a fresh copy
final Album fetchedAlbum = em.find(Album.class, album.getId());
expectedLifecycle.add(new CallbackLogEntry(fetchedAlbum, PostLoad.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// delete it
em.remove(fetchedAlbum);
em.flush();
expectedLifecycle.add(new CallbackLogEntry(fetchedAlbum, PreRemove.class));
expectedLifecycle.add(new CallbackLogEntry(fetchedAlbum, PostRemove.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
}
public void testUpdateEntityLifecycle() throws Exception {
assertTrue(TestingGlobalEntityListener.CALLBACK_LOG.isEmpty());
// make it
final Album album = new Album();
album.setArtist(null);
album.setName("Abbey Road");
album.setReleaseDate(new Date(-8366400000L));
// store it
final EntityManager em = getEntityManager();
em.persist(album);
em.flush();
final List<CallbackLogEntry> expectedLifecycle = new ArrayList<>();
expectedLifecycle.add(new CallbackLogEntry(album, PrePersist.class));
expectedLifecycle.add(new CallbackLogEntry(album, PostPersist.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
// modify it
album.setName("Cowabunga");
em.flush();
expectedLifecycle.add(new CallbackLogEntry(album, PreUpdate.class));
expectedLifecycle.add(new CallbackLogEntry(album, PostUpdate.class));
assertEquals(expectedLifecycle, TestingGlobalEntityListener.CALLBACK_LOG);
}
/**
* Regression test for ERRAI-611.
*/
public void testNoEventFromIdGeneratorProbe() throws Exception {
// create an album with an artist, which we will probe for with the NO_SIDE_EFFECTS option
final Artist artist = new Artist();
artist.setId(123L);
artist.setName("The Beatles");
final Album album = new Album();
album.setArtist(artist);
album.setName("Abbey Road");
album.setReleaseDate(new Date(-8366400000L));
// store them
final EntityManager em = getEntityManager();
em.persist(artist);
em.persist(album);
em.flush();
em.clear();
TestingGlobalEntityListener.CALLBACK_LOG.clear();
final ErraiEntityManager eem = (ErraiEntityManager) em;
assertTrue(eem.isKeyInUse(eem.keyFor(album)));
// Finally, ensure there were no events fired as a result of the probe
// (originally, we were getting a PostLoad for artist, because it was being cascade-fetched from album)
assertEquals("[]", TestingGlobalEntityListener.CALLBACK_LOG.toString());
}
}