Always getting a empty object in unitTest JPA/Hibernate - spring-boot

I am currently trying if my functions work with my current database but I keep getting an empty object back. My Test is the following:
#Test
public void findJobOfferByIdReturnsCorrectJobOffer() {
User user = UserBuilder.anUser().build();
JobOffer firstJobOffer = JobOfferBuilder.aJobOffer()
.withId(108L)
.withCompany(user)
.build();
JobOffer secondJoboffer = JobOfferBuilder.aJobOffer()
.withAmountPerSession(55)
.withCompany(user)
.withId(208L)
.withJobDescription("Software Tester in PHP")
.build();
userDao.saveUser(user);
jobOfferDao.saveJobOffer(firstJobOffer);
jobOfferDao.saveJobOffer(secondJoboffer);
entityManager.clear();
entityManager.flush();
Optional<JobOffer> retrievedJobOffer = jobOfferDao.findJobOfferById(firstJobOffer.getId());
assertTrue(retrievedJobOffer.isPresent());
JobOffer jobOffer = retrievedJobOffer.get();
assertEquals(jobOffer.getId(), firstJobOffer.getId());
assertNotEquals(jobOffer.getId(), secondJoboffer.getId());
}
The Test uses the following DAOImpl repository:
#Repository
public class JobOfferDaoImpl implements JobOfferDao {
#PersistenceContext
private EntityManager entityManager;
private static final Logger LOGGER = LogManager.getLogger(UserDaoImpl.class);
#Override
public Optional<JobOffer> findJobOfferById(Long id) {
TypedQuery<JobOffer> jobOfferQuery = entityManager.createNamedQuery("findJobOfferById", JobOffer.class);
jobOfferQuery.setParameter("jobOfferId", id);
try {
return Optional.of(jobOfferQuery.getSingleResult());
} catch (NoResultException e) {
return Optional.empty();
}
}
#Transactional
public void saveJobOffer(JobOffer jobOffer) {
if (findJobOfferById(jobOffer.getId()).isEmpty()) {
entityManager.merge(jobOffer);
LOGGER.info(String.format("Joboffer with id %d is inserted in the database", jobOffer.getId()));
} else {
throw new JobOfferNotFoundException();
}
}
}
And the Query to select the correct jobOffer for "findJobOfferById" is the following:
#NamedQuery(name = "findJobOfferById", query = "SELECT j from JobOffer j WHERE j.id = :jobOfferId"),
When trying to debug I get the following:

In the Test you shouldn't give your own ID. Change it with:
.withId(null)
And in the DAO you have to Persist the jobOffer and actually add it. With merge you are modifying it.
entityManager.persist(jobOffer);

Related

Spring Integration DSL - JdbcPollingChannelAdapter results not queueing

I swear I had this working, but when I can back to it after a few months (and an upgrade to Boot 1.5.9), I am having issues.
I set up a JdbcPollingChannelAdapter that I can do a receive() on just fine, but when I put the adapter in a flow that does nothing more than queue the result of the adapter, running .receive on the queue always returns a null (I can see in the console log that the adapter's SQL getting executed, though).
Tests below. Why can I get results from the adapter, but not queue the results? Thank you in advance for any assistance.
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureTestDatabase
#JdbcTest
public class JdbcpollingchanneladapterdemoTests {
#Autowired
#Qualifier("dataSource")
DataSource dataSource;
private static PollableChannel outputQueue;
#BeforeClass
public static void setupClass() {
outputQueue = MessageChannels.queue().get();
return;
}
#Test
public void Should_HaveQueue() {
assertThat(outputQueue, instanceOf(QueueChannel.class));
}
#Test
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Create Table DEMO (CODE VARCHAR(5));")
#Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD,
statements = "Drop Table DEMO ;")
public void Should_Not_HaveMessageOnTheQueue_When_No_DemosAreInTheDatabase() {
Message<?> message = outputQueue.receive(5000);
assertThat(message, nullValue()) ;
}
#Test
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Create Table DEMO (CODE VARCHAR(5));")
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Insert into DEMO (CODE) VALUES ('12345');")
#Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD,
statements = "Drop Table DEMO ;")
public void Should_HaveMessageOnTheQueue_When_DemosIsInTheDatabase() {
assertThat(outputQueue, instanceOf(QueueChannel.class));
Message<?> message = outputQueue.receive(5000);
assertThat(message, notNullValue());
assertThat(message.getPayload().toString(), equalTo("15317")) ;
}
#Test
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Create Table DEMO (CODE VARCHAR(5));")
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Insert into DEMO (CODE) VALUES ('12345');")
#Sql(executionPhase = ExecutionPhase.AFTER_TEST_METHOD,
statements = "Drop Table DEMO ;")
public void get_message_directly_from_adapter() {
JdbcPollingChannelAdapter adapter =
new JdbcPollingChannelAdapter(dataSource, "SELECT CODE FROM DEMO");
adapter.setRowMapper(new DemoRowMapper());
adapter.setMaxRowsPerPoll(1);
Message<?> message = adapter.receive();
assertThat(message, notNullValue());
}
private static class Demo {
private String demo;
String getDemo() {
return demo;
}
void setDemo(String value) {
this.demo = value;
}
#Override
public String toString() {
return "Demo [value=" + this.demo + "]";
}
}
public static class DemoRowMapper implements RowMapper<Demo> {
#Override
public Demo mapRow(ResultSet rs, int rowNum) throws SQLException {
Demo demo = new Demo();
demo.setDemo(rs.getString("CODE"));
return demo;
}
}
#Component
public static class MyFlowAdapter extends IntegrationFlowAdapter {
#Autowired
#Qualifier("dataSource")
DataSource dataSource;
#Override
protected IntegrationFlowDefinition<?> buildFlow() {
JdbcPollingChannelAdapter adapter =
new JdbcPollingChannelAdapter(dataSource, "SELECT CODE FROM DEMO");
adapter.setRowMapper(new DemoRowMapper());
adapter.setMaxRowsPerPoll(1);
return from(adapter,
c -> c.poller(Pollers.fixedRate(1000L, 2000L)
.maxMessagesPerPoll(1)
.get()))
.channel(outputQueue);
}
}
}
EDIT I've simplified it as much as I can, refactoring to code below. The test passes a flow with a generic message source, and fails on a flow with JdbcPollingChannelAdapter message source. It's just not evident to me how I should configure the second message source so that it will suceed like the first message source.
#Test
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Create Table DEMO (CODE VARCHAR(5));")
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Insert into DEMO (CODE) VALUES ('12345');")
public void Should_HaveMessageOnTheQueue_When_UnsentDemosIsInTheDatabase() {
this.genericFlowContext.registration(new GenericFlowAdapter()).register();
PollableChannel genericChannel = this.beanFactory.getBean("GenericFlowAdapterOutput",
PollableChannel.class);
this.jdbcPollingFlowContext.registration(new JdbcPollingFlowAdapter()).register();
PollableChannel jdbcPollingChannel = this.beanFactory.getBean("JdbcPollingFlowAdapterOutput",
PollableChannel.class);
assertThat(genericChannel.receive(5000).getPayload(), equalTo("15317"));
assertThat(jdbcPollingChannel.receive(5000).getPayload(), equalTo("15317"));
}
private static class GenericFlowAdapter extends IntegrationFlowAdapter {
#Override
protected IntegrationFlowDefinition<?> buildFlow() {
return from(getObjectMessageSource(),
e -> e.poller(Pollers.fixedRate(100)))
.channel(c -> c.queue("GenericFlowAdapterOutput"));
}
private MessageSource<Object> getObjectMessageSource() {
return () -> new GenericMessage<>("15317");
}
}
private static class JdbcPollingFlowAdapter extends IntegrationFlowAdapter {
#Autowired
#Qualifier("dataSource")
DataSource dataSource;
#Override
protected IntegrationFlowDefinition<?> buildFlow() {
return from(getObjectMessageSource(),
e -> e.poller(Pollers.fixedRate(100)))
.channel(c -> c.queue("JdbcPollingFlowAdapterOutput"));
}
private MessageSource<Object> getObjectMessageSource() {
JdbcPollingChannelAdapter adapter =
new JdbcPollingChannelAdapter(dataSource, "SELECT CODE FROM DEMO");
adapter.setRowMapper(new DemoRowMapper());
adapter.setMaxRowsPerPoll(1);
return adapter;
}
}
Looks like you need to add #EnableIntegration to your test configuration.
When you use Spring Boot slices for testing, not all auto-configurations are loaded:
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#test-auto-configuration
UPDATE
The problem that JdbcPollingChannelAdapter is run in the separate, scheduled thread, already out of the original transaction around test method, where those #Sqls are performed.
The fix for you is like this:
#Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD,
statements = "Insert into DEMO (CODE) VALUES ('12345');",
config = #SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
Pay attention to that SqlConfig.TransactionMode.ISOLATED. This way the INSERT transaction is committed and the data is available for that separate polling thread for the JdbcPollingChannelAdapter.
Also pay attention that this JdbcPollingChannelAdapter always returns a List of records. So, your assertThat(jdbcPollingChannel.receive(5000).getPayload(), ...); should be against a List<String> even if there is only one record in the table.

Spring + Hibernate + TestNG + Mocking nothing persist, nothing is readed in test

Fighting with TestNG, Spring an Hibernate. I'm writing test for Service class, and it's always failure. But without test class works fine. So App is working, but tests don't want to.
Here is my test class
#Transactional
public class BorrowerServiceTest {
#Mock
BorrowerDAOImpl borrowerDAO;
#InjectMocks
BorrowerService borrowerService;
#BeforeClass
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void persistTest() {
Borrower borrower = new Borrower.BorrowerBuilder().firstName("Lars").lastName("Urlich").adress("LA")
.phoneNumber("900900990").build();
borrowerService.persist(borrower);
List<Borrower> borrowerList = borrowerService.getBorrowerByName("Lars Urlich");
Assert.assertEquals(true, borrower.equals(borrowerList.get(0)));
}
}
My BorrowerService:
#Service("borrowerService")
#Transactional
public class BorrowerService {
#Autowired
private BorrowerDAO borrowerDAO;
public List<Borrower> getBorrowers() {
return borrowerDAO.getBorrowers();
}
public List<Borrower> getBorrowerByName(String name) {
return borrowerDAO.getBorrowerByName(name);
}
public boolean removeBorrower(Borrower borrower) {
return borrowerDAO.removeBorrower(borrower);
}
public boolean persist(Borrower borrower) {
return borrowerDAO.persist(borrower);
}
}
My BorrowerDAOImpl:
#Repository("borrowerDAO")
#Transactional
public class BorrowerDAOImpl extends DAO implements BorrowerDAO {
#Override
public List<Borrower> getBorrowers() {
List<Borrower> borrowerList = null;
Query query = entityManager.createQuery("SELECT B FROM Borrower B");
borrowerList = query.getResultList();
return borrowerList;
}
#Override
public List<Borrower> getBorrowerByName(String name) {
List<Borrower> borrowerList = null;
String[] values = name.split(" ");
Query query = entityManager.createQuery("SELECT B FROM Borrower B WHERE B.firstName LIKE '" + values[0]
+ "' AND B.lastName LIKE '" + values[1] + "'");
borrowerList = query.getResultList();
return borrowerList;
}
#Override
public boolean removeBorrower(Borrower borrower) {
String firstName = borrower.getFirstName();
String lastName = borrower.getLastName();
Query query = entityManager
.createQuery("DELETE Borrower where FIRST_NAME LIKE :FirstName AND LAST_NAME LIKE :LastName");
query.setParameter("FirstName", firstName);
query.setParameter("LastName", lastName);
query.executeUpdate();
return true;
}
#Override
public boolean persist(Borrower borrower) {
entityManager.persist(borrower);
return true;
}
}
and abstract DAO:
#Repository
#Transactional
public abstract class DAO {
#PersistenceContext
protected EntityManager entityManager;
}
Maven returns failure:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.get(LinkedList.java:476)
at com.me.service.test.BorrowerServiceTest.persistTest(BorrowerServiceTest.java:41)
I also had to fight with this. The problem here is that your test runs in it's own transaction, so nothing will be committed during method's execution. Now here is what I did:
public class IntegrationTest extends SomeTestBase
{
#Autowired
private PlatformTransactionManager platformTransactionManager;
private TransactionTemplate transactionTemplate;
#Autowired
private BeanToTest beanToTest;
#Override
#Before
public void setup()
{
super.setup();
this.transactionTemplate = new TransactionTemplate(this.platformTransactionManager);
}
#Test
public void fooTest()
{
// given
// when
boolean result = this.transactionTemplate.execute(new TransactionCallback<Boolean>()
{
#Override
public Boolean doInTransaction(TransactionStatus status)
{
return IntegrationTest.this.beanToTest.foo();
}
});
// then
}
}
This allows you to have methods execute within a separate transaction. Please note that you might declare some variables as final.
Hope that helps.
Check the Spring documentation: it looks your test class should extend AbstractTestNGSpringContextTests.
Use #Commit annotation on the whole test class or even method to persist changes made in the test. For more information https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#commit

Transactions and relationship entities mapping problems with Neo4j OGM

Versions used: spring-data-neo4j 4.2.0-BUILD-SNAPSHOT / neo4j-ogm 2.0.6-SNAPSHOT
I'm having problems to correctly fetch relationship entities.
The following fetch calls don't return consistent results (executed in the same transaction):
session.query("MATCH (:A)-[b:HAS_B]-(:C) RETURN count(b) as count") returns 1
session.query("MATCH (:A)-[b:HAS_B]-(:C) RETURN b") correctly returns the relationship entity as a RelationshipModel object
session.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) RETURN b") returns null !
Important remark: When all operations (create, fetch) are done in the same transaction, it seems to be fine.
I have been able to implement a workaround by using session.query(String, Map) to query the relationship entity and map it by myself into my POJO.
#NodeEntity
public class A {
public A () {}
public A (String name) {
this.name = name;
}
#GraphId
private Long graphId;
private String name;
#Relationship(type="HAS_B", direction=Relationship.OUTGOING)
private B b;
}
#RelationshipEntity(type="HAS_B")
public class B {
public B () {}
public B (String name, A a, C c) {
this.name = name;
this.a = a;
this.c = c;
}
#GraphId
private Long graphId;
#StartNode
private A a;
#EndNode
private C c;
private String name;
}
#NodeEntity
public class C {
public C () {}
public C (String name) {
this.name = name;
}
#GraphId
private Long graphId;
private String name;
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={MyTest.TestConfiguration.class})
public class MyTest {
#Autowired
private MyBean myBean;
#Configuration
#EnableAutoConfiguration
#EnableTransactionManagement
#EnableNeo4jRepositories("com.nagra.ml.sp.cpm.core.repositories")
public static class TestConfiguration {
#Bean
public org.neo4j.ogm.config.Configuration configuration() {
org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration();
config.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
return config;
}
#Bean
public SessionFactory sessionFactory() {
return new SessionFactory(configuration(), "com.nagra.ml.sp.cpm.model");
}
#Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
#Bean
public MyBean myBean() {
return new MyBean();
}
}
#Test
public void alwaysFails() {
myBean.delete();
myBean.create("1");
try { Thread.sleep(2000); } catch (InterruptedException e) {} //useless
myBean.check("1"); // FAILS HERE !
}
#Test
public void ok() {
myBean.delete();
myBean.createAndCheck("2");
}
}
#Transactional(propagation = Propagation.REQUIRED)
public class MyBean {
#Autowired
private Session neo4jSession;
public void delete() {
neo4jSession.query("MATCH (n) DETACH DELETE n", new HashMap<>());
}
public void create(String suffix) {
C c = new C("c"+suffix);
neo4jSession.save(c);
A a = new A("a"+suffix);
neo4jSession.save(a);
B bRel = new B("b"+suffix, a, c);
neo4jSession.save(bRel);
}
public void check(String suffix) {
//neo4jSession.clear(); //Not working even with this
Number countBRels = (Number) neo4jSession.query("MATCH (:A)-[b:HAS_B]-(:C) WHERE b.name = 'b"+suffix+"' RETURN count(b) as count", new HashMap<>()).iterator().next().get("count");
assertEquals(1, countBRels.intValue()); // OK
Iterable<B> bRels = neo4jSession.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) WHERE b.name = 'b"+suffix+"' RETURN b", new HashMap<>());
boolean relationshipFound = bRels.iterator().hasNext();
assertTrue(relationshipFound); // FAILS HERE !
}
public void createAndCheck(String suffix) {
create(suffix);
check(suffix);
}
}
This query session.query(B.class, "MATCH (:A)-[b:HAS_B]-(:C) RETURN b") returns only the relationship but not the start node or end node and so the OGM cannot hydrate this. You need to always return the start and end node along with the relationship like session.query(B.class, "MATCH (a:A)-[b:HAS_B]-(c:C) RETURN a,b,c")
The reason it appears to work when you both create and fetch data in the same transaction is that the session already has a cached copy of a and c and hence b can be hydrated with cached start and end nodes.
Firstly, please upgrade from OGM 2.0.6-SNAPSHOT to 2.1.0-SNAPSHOT. I have noticed some off behaviour in the former which might be one part of the issue.
Now on to your test. There are several things going on here which are worth investigating.
Use of #DirtiesContext: You don't seem to be touching the context and if you are using it to reset the context between tests so you get a new Session/Transaction then that's going about it the wrong way. Just use #Transactional instead. The Spring JUnit runner will treat this in a special manner (see next point).
Being aware that Transactional tests automatically roll back: Jasper is right. Spring Integration Tests will always roll back by default. If you want to make sure your JUnit test commits then you will have to #Commit it. A good example of how to set up your test can be seen here.
Knowing how Spring Transaction proxies work. On top of all this confusion you have to make sure you don't simply call transactional method to transactional method in the same class and expect Spring's Transactional behaviour to apply. A quick write up on why can be seen here.
If you address those issues everything should be fine.

Spring , Transactions , Hibernate Filters

I am using declarative transactions in Spring. I have a service layer which is annotated with "Transactional". This service layer calls the DAO. I need to enable a hibernate filter in all the dao methods. I don't want to have to explicitly call teh session.enablefilter each time. So is there a way using spring transaction aop etc such that a intercepter can be called when the hibernate session is created?
My Service layer:
#Service("customerViewService")
#Transactional
public class CustomerViewServiceImpl extends UFActiveSession implements CustomerViewService {
private static final Logger log = LoggerFactory.getLogger(CustomerViewServiceImpl.class);
private CustomerDAO daoInstance = null;
private CustomerDAO getCustomerDAO() {
if (daoInstance == null)
daoInstance = DAOFactory.getDao(CustomerDAO.class);
return daoInstance;
}
#Transactional(propagation=Propagation.REQUIRED, rollbackFor=DAOException.class)
public CustomerModel getCustomerModel() throws UFClientException {
CustomerModel model = null;
try {
Customer customerTbl = getCustomerDAO().getCustomerDetail(getUserName());
if (customerTbl == null) {
log.error("DAO-02: No entry found for Customer id- " + getUserName());
throw new UFClientException("DAO-02");
}
model = DozerConverter.hibernateToDto(customerTbl, CustomerModel.class);
}
catch (DAOException e) {
log.error("DAO-01: Not able to fetch entry from database for customer.");
throw new UFClientException();
}
return model;
}
}
My Dao Layer
public class CustomerDAOImpl extends HibernateDaoSupport implements CustomerDAO {
#SuppressWarnings("unchecked")
public Customer getCustomerDetail(String email) throws DAOException {
try {
List<Customer> customers = getHibernateTemplate().find(sb.toString(), email);
if (customers.size() == 0)
return null;
return customers.get(0);
}
catch (Exception e) {
throw new DAOException(e);
}
}
Appreciate your help!!
You can create your own interceptor, and apply it to methods that havbe transactional:
#AroundInvoke("#annotation(transactional)")
public ... handle(Transactional transactional) {
...
}

Cannot delete entity (JPA & Spring)

What ever I try, I cannot delete a user entity when I call delete() from my userService class. I get an exception java.lang.IllegalArgumentException: Entity must be managed to call remove: com.blackbox.genesis.entities.User#30168a, try merging the detached and try the remove again. I'm obviously doing something wrong - despite merging, but I can't see what. Everything else works fine - I can create and update user entities without any problem.
Regards
My entity class;
#Entity
#Table(uniqueConstraints = {#UniqueConstraint(columnNames = "EMAIL")})
public class User implements Serializable {
#Id
#Column(name="username", length=50)
private String username;
#OneToOne(cascade = {CascadeType.ALL})
private Password password;
private boolean enabled;
private int serial;
private String email;
#Version
private int version;
#ElementCollection(targetClass=Authority.class)
#CollectionTable(name="USER_AUTHORITY")
private List<Authority> authorities;
#OneToMany(mappedBy="user", fetch=FetchType.LAZY, cascade=CascadeType.ALL, ``orphanRemoval=true)
private Set<License> licenses;
private static final long serialVersionUID = 1L;
public User() {
super();
this.authorities = new ArrayList<Authority>();
}
.... getters/setters.
My DAO class;
#Repository
public class UserJpaController {
#PersistenceContext
EntityManager em;
protected static final Logger logger = Logger.getLogger("com.blackbox.genesisng.entities.UsersJpaController");
public void create(User user) throws PreexistingEntityException, Exception {
if (findUser(user.getUsername()) != null) {
throw new PreexistingEntityException("Users " + user + " already exists.");
}
em.persist(user);
em.flush();
}
public void edit(User user) throws NonexistentEntityException, Exception {
user = em.merge(user);
em.flush();
}
public void destroy(String id) throws NonexistentEntityException {
User user = em.find(User.class, id);
user = em.merge(user);
em.remove(user);
}
public List<User> findUserEntities() {
return findUserEntities(true, -1, -1);
}
public List<User> findUserEntities(int maxResults, int firstResult) {
return findUserEntities(false, maxResults, firstResult);
}
private List<User> findUserEntities(boolean all, int maxResults, int firstResult) {
Query q = em.createQuery("select object(o) from User as o");
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
}
public User findUser(String id) {
return em.find(User.class, id);
}
public int getUserCount() {
Query q = em.createQuery("select count(o) from User as o");
return ((Long) q.getSingleResult()).intValue();
}
public User findUserByEmail(String email) {
Query q = em.createQuery("select Object(o) from User as o where o.email = :email");
q.setParameter("email", email);
List list = q.getResultList();
if (list.size() == 0) {
return null;
}
return (User) list.get(0);
}
public boolean exists(String id) {
try {
em.getReference(User.class,id);
return true;
}
catch (EntityNotFoundException e) {
return false;
}
}
}
and finally, the relevant portion of my service class
#Service
public class UserService {
#Autowired
UserJpaController dao;
#Autowired
LicenseJpaController licenseDao;
#Transactional
public void delete(UserDTO userDTO) {
if (exists(userDTO.getUserName())){
try {
dao.destroy(userDTO.getUserName());
} catch (NonexistentEntityException e) {
// ignore as the previous test should prevent this.
}
}
}
So sorry, but I'm an idiot! I was not calling the service class that I thought I was. Fixed that and everything works as expected. Once again, sorry folks.
Regards
Remove the
user = em.merge(user);
statement in your DAO destroy method. I am not sure if it causes the probem, but it is not needed because the user is loaded in the statement before.

Resources