org.dbunit.dataset.NoSuchTableException: While loading dataset to view - dbunit

I'm looking forward to integrate dbUnit to a project. The project has Spring and has no ORM. While loading the XML dataSet to the db i'm getting
org.dbunit.dataset.NoSuchTableException: XXX_VW
"XXX_VW" is a db view. However, I'm able to load the dataset to any table. I've confirmed in db the required view exits and the metadata is similiar.
Below is the code I execute during setup method of my test.
DataSource dc = (MCDataSource) context.getBean("dataSource");
databaseTester = new DataSourceDatabaseTester(dc, dc.getUsername());
DatabaseConfig config = databaseTester.getConnection().getConfig();
config.setProperty(DatabaseConfig.PROPERTY_TABLE_TYPE, new String[]{"TABLE", "VIEW"});
databaseTester.setDataSet(this.getDataSet());
databaseTester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
databaseTester.onSetup();
Any idea what could be the issue ?

Instead implement and setOperationListener and do setProperty during lifecycle methods of OperationListener.
databaseTester.setOperationListener(new IOperationListener() {
#Override
public void operationTearDownFinished(IDatabaseConnection connection) {
// TODO Auto-generated method stub
}
#Override
public void operationSetUpFinished(IDatabaseConnection connection) {
// TODO Auto-generated method stub
}
#Override
public void connectionRetrieved(IDatabaseConnection connection) {
DatabaseConfig config = connection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_TABLE_TYPE, new String[]{"TABLE", "VIEW"});
databaseTester.setDataSet(this.getDataSet());
databaseTester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
databaseTester.onSetup();

Related

How to rollback child transaction if any exception in parent transaction?

I have two transaction manager for two database. I need to persist same data into both databases. If one transaction failed, other one need rollback. I have done like below
public interface DataService {
void saveData();
}
#Service
public class DataServiceImpl implements DataService {
#Autowired
private DataRepository dataRepository;
#Autowired
private OrDataRepository orDataRepository;
#Autowired
#Qualifier("orService")
private OrService orDataServiceImpl;
#Override
#Transactional(transactionManager = "transactionManager", rollbackFor = {RuntimeException.class})
public void saveData() {
Data data = new Data();
data.setCompKey(UUID.randomUUID().toString().substring(1,5));
data.setName("data");
dataRepository.save(data);
orDataServiceImpl.save();
//throw new RuntimeException("");
}
}
public interface OrService {
void save();
}
#Service("orService")
public class OrDataServiceImpl implements OrService {
#Autowired
private OrDataRepository orDataRepository;
#Override
#Transactional(rollbackFor = {RuntimeException.class})
public void save() {
OrData data = new OrData();
data.setCompKey(UUID.randomUUID().toString().substring(1,5));
data.setName("ordata");
orDataRepository.save(data);
}
}
I have two transaction manager (entityManager & orEntityManager) for two different DB.
If any exception in OrDataServiceImpl save method, data is not getting persisted in both DB. But if any exception in DataServiceImpl saveData method, data is getting persisted into OrData table.
I want to rollback the data from both DB if any exception.
chainedTransactionManager is deprecated. So can't use. atomikos and bitronix also can't use due to some restrictions. Kindly suggest better way to achieve distributed transation
The code need to be refactored, edit the DataServiceImpl.save() method.
Comment the orDataServiceImpl.save() line
public void saveData() {
Data data = new Data();
data.setCompKey(UUID.randomUUID().toString().substring(1,5));
data.setName("data");
dataRepository.save(data);
//orDataServiceImpl.save();
//throw new RuntimeException("");
}
Refactor/Edit the OrDataService Interface
public interface OrDataService {
void save(String uuid);
void delete(String uuid);
//will be use for compensating transaction
}
Update the OrDataServiceImpl class to implement above interface
Write new orchestration Method and use compensating transaction to rollback
pseudo code
call OrDataServiceImpl.save()
if step#1 was success
-> DataServiceImpl.saveData()
if Exception at step#3,
->OrDataServiceImpl.delete() [//to rollback]
else if, Exception at step#1
//do nothing

Add camel route at runtime using end points configured in property file

I own a spring application and want to add camel routes dynamically during my application startup.End points are configured in property file and are loaded at run time.
Using Java DSL, i am using for loop to create all routes,
for(int i=0;i<allEndPoints;i++)
{
DynamcRouteBuilder route = new
DynamcRouteBuilder(context,fromUri,toUri)
camelContext.addRoutes(route)
}
private class DynamcRouteBuilder extends RouteBuilder {
private final String from;
private final String to;
private MyDynamcRouteBuilder(CamelContext context, String from, String to) {
super(context);
this.from = from;
this.to = to;
}
#Override
public void configure() throws Exception {
from(from).to(to);
}
}
but getting below exception while creating first route itself
Failed to create route file_routedirect: at: >>> OnException[[class org.apache.camel.component.file.GenericFileOperationFailedException] -> [Log[Exception trapped ${exception.class}], process[Processor#0x0]]] <<< in route: Route(file_routedirect:)[[From[direct:... because of ref must be specified on: process[Processor#0x0]\n\ta
Not sure about it- what is the issue ? Can someone has any suggestion or fix for this. Thanks
Well, to create routes in an iteration it is nice to have some object that holds the different values for one route. Let's call this RouteConfiguration, a simple POJO with String fields for from, to and routeId.
We are using YAML files to configure such things because you have a real List format instead of using "flat lists" in property files (route[0].from, route[0].to).
If you use Spring you can directly transform such a "list of object configurations" into a Collection of objects using #ConfigurationProperties
When you are able to create such a Collection of value objects, you can simply iterate over it. Here is a strongly simplified example.
#Override
public void configure() {
createConfiguredRoutes();
}
void createConfiguredRoutes() {
configuration.getRoutes().forEach(this::addRouteToContext);
}
// Implement route that is added in an iteration
private void addRouteToContext(final RouteConfiguration routeConfiguration) throws Exception {
this.camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from(routeConfiguration.getFrom())
.routeId(routeConfiguration.getRouteId())
...
.to(routeConfiguration.getTo());
}
});
}

Weblogic,EJB, $Proxy99 class cast exception

Following are the modules in my project,
1. EJB module (version 3): We prepare ejb jar of this module and deploy on Weblogic11g server. It deals with database operation. It has #local, #Remote interface and #stateless classes implementing #local,#Remote interfaces.
2. Web Application : This web application takes inputs (user uploads file) from users, validates file and inserts data into database. It uses RMI.
Problem: On production (weblogic 11g server ) sometimes we observe exception saying $Proxy99 cannot be cast to "Remote interface name" (for different different classes) e.g com.xyz.fileProcessSetting.FileProcessSttgFacadeRemote.
But after some time when we again upload file, it gets uploaded successfully without any error.
Now, I do not understand how come these remote objects becomes temporarily unavailable? Never faced this issue on development/UAT environment. Also no idea how to reproduce and fix it.
Please help. Thanks in advance.
#Remote
public interface FileProcessSttgFacadeRemote {
//methods
}
#Local
public interface FileProcessSttgFacadeLocal {
//methods
}
#Stateless
public class FileProcessSttgFacade implements FileProcessSttgFacadeLocal, FileProcessSttgFacadeRemote {
//methods
}
in weblogic-ejb-jar.xml
<weblogic-enterprise-bean>
<ejb-name>FileProcessSttgFacade</ejb-name>
<stateless-session-descriptor>
<business-interface-jndi-name-map>
<business-remote>com.xyz.fileProcessSetting.FileProcessSttgFacadeRemote</business-remote>
<jndi-name>FileProcessSttgFacade</jndi-name>
</business-interface-jndi-name-map>
</stateless-session-descriptor>
</weblogic-enterprise-bean>
In web application also in ejb module whenever we want to call methods we use following lookup method to get remote object:
public class someclass extends EjbLocator {
public void someMethod(){
FileProcessSttgFacadeRemote fpfr = (FileProcessSttgFacadeRemote) getService("FileProcessSttgFacade");
//other code
}
}
Following is the class used for JNDI lookup:
public class EjbLocator {
public Object getService(final String jndiName) throws Exception {
try {
obj = getDefaultContext().lookup(jndiName);
} catch (final Exception exp) {
exp.printStackTrace();
}
return obj;
}
protected Context getDefaultContext() {
try {
final Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL,"weblogic");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put(Context.PROVIDER_URL, "t3://<ip>:<port>");
defaultContext = new InitialContext(env);
return defaultContext;
} catch (final NamingException nExp) {
nExp.printStackTrace();
}
return null;
}
}

Unit Testing Spring ApplicationEvents - Events are getting published but the listeners aren't firing?

I'm trying to unit test the custom events that I've created in Spring and am running into an interesting problem. If I create a StaticApplicationContext and manually register and wire the beans I can trigger events and see the program flow through the publisher (implements ApplicationEventPublisherAware) through to the listener (implements ApplicationListener<?>).
Yet when I try to create a JUnit test to create the context using the SpringJunit4ClassRunner and #ContextConfiguration everything works well except that the ApplicationEvents are not showing up in the listener (I have confirmed that they are getting published).
Is there some other way to create the context so that ApplicationEvents will work correctly? I haven't found much on the web about unit testing the Spring events framework.
The events will not fire because your test classes are not registered and resolved from the spring application context, which is the event publisher.
I've implemented a workaround for this where the event is handled in another class that is registered with Spring as a bean and resolved as part of the test. It isn't pretty, but after wasting the best part of a day trying to find a better solution I am happy with this for now.
My use case was firing an event when a message is received within a RabbitMQ consumer. It is made up of the following:
The wrapper class
Note the Init() function that is called from the test to pass in the callback function after resolving from the container within the test
public class TestEventListenerWrapper {
CountDownLatch countDownLatch;
TestEventWrapperCallbackFunction testEventWrapperCallbackFunction;
public TestEventListenerWrapper(){
}
public void Init(CountDownLatch countDownLatch, TestEventWrapperCallbackFunction testEventWrapperCallbackFunction){
this.countDownLatch = countDownLatch;
this.testEventWrapperCallbackFunction = testEventWrapperCallbackFunction;
}
#EventListener
public void onApplicationEvent(MyEventType1 event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
#EventListener
public void onApplicationEvent(MyEventType2 event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
#EventListener
public void onApplicationEvent(OnQueueMessageReceived event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
}
The callback interface
public interface TestEventWrapperCallbackFunction {
void CallbackOnEventFired(ApplicationEvent event);
}
A test configuration class to define the bean which is referenced in the unit test. Before this is useful, it will need to be resolved from the applicationContext and initialsed (see next step)
#Configuration
public class TestContextConfiguration {
#Lazy
#Bean(name="testEventListenerWrapper")
public TestEventListenerWrapper testEventListenerWrapper(){
return new TestEventListenerWrapper();
}
}
Finally, the unit test itself that resolves the bean from the applicationContext and calls the Init() function to pass assertion criteria (this assumes you have registered the bean as a singleton - the default for the Spring applicationContext). The callback function is defined here and also passed to Init().
#ContextConfiguration(classes= {TestContextConfiguration.class,
//..., - other config classes
//..., - other config classes
})
public class QueueListenerUnitTests
extends AbstractTestNGSpringContextTests {
private MessageProcessorManager mockedMessageProcessorManager;
private ChannelAwareMessageListener queueListener;
private OnQueueMessageReceived currentEvent;
#BeforeTest
public void Startup() throws Exception {
this.springTestContextPrepareTestInstance();
queueListener = new QueueListenerImpl(mockedMessageProcessorManager);
((QueueListenerImpl) queueListener).setApplicationEventPublisher(this.applicationContext);
currentEvent = null;
}
#Test
public void HandleMessageReceived_QueueMessageReceivedEventFires_WhenValidMessageIsReceived() throws Exception {
//Arrange
//Other arrange logic
Channel mockedRabbitmqChannel = CreateMockRabbitmqChannel();
CountDownLatch countDownLatch = new CountDownLatch(1);
TestEventWrapperCallbackFunction testEventWrapperCallbackFunction = (ev) -> CallbackOnEventFired(ev);
TestEventListenerWrapper testEventListenerWrapper = (TestEventListenerWrapper)applicationContext.getBean("testEventWrapperOnQueueMessageReceived");
testEventListenerWrapper.Init(countDownLatch, testEventWrapperCallbackFunction);
//Act
queueListener.onMessage(message, mockedRabbitmqChannel);
long awaitTimeoutInMs = 1000;
countDownLatch.await(awaitTimeoutInMs, TimeUnit.MILLISECONDS);
//Assert - assertion goes here
}
//The callback function that passes the event back here so it can be made available to the tests for assertion
private void CallbackOnEventFired(ApplicationEvent event){
currentEvent = (OnQueueMessageReceived)event;
}
}
EDIT 1: The sample code has been updated with CountDownLatch
EDIT 2: Assertions didn't fail tests so the above was updated with a different approach**
I just run my app as SpringBootTest, application events working fine:
#TestComponent
public class EventTestListener {
#EventListener
public void handle(MyCustomEvent event) {
// nothing to do, just spy the method...
}
}
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyEventTest {
#SpyBean
private EventTestListener testEventListener;
#Test
public void testMyEventFires() {
// do something that fires the event..
verify(testEventListener).handle(any(MyCustomEvent.class));
}
}
use the #Captor / ArgumentCaptor to verify the content of your event.
You can create a context manually.
For example: I had needed to check if my ApplicationListener<ContextClosedEvent> closed Cassandra connections:
#Test
public void testSpringShutdownHookForCassandra(){
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CassandraConfig.class);
CassandraConnectionManager connectionManager = ctx.getBean(CassandraConnectionManager.class);
Session session = connectionManager.openSession(testKeySpaceName);
Assert.assertFalse( session.isClosed() );
ctx.close();
Assert.assertTrue( session.isClosed() );
}

Nhibernate with windows form

I have a asp.net application with Nihbernate setup, now I want to convert it to Windows form application.
Here is the code which have been setup in the Global.asax.cs. Can anyone give me some code sample how to do this in Windows form?
protected void Application_BeginRequest(object sender, EventArgs e)
{
ManagedWebSessionContext.Bind(HttpContext.Current, SessionManager.SessionFactory.OpenSession());
}
protected void Application_EndRequest(object sender, EventArgs e)
{
ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, SessionManager.SessionFactory);
if (session != null)
{
try
{
if (session.Transaction != null && session.Transaction.IsActive)
{
session.Transaction.Rollback();
}
else
{
session.Flush();
}
}
finally
{
session.Close();
}
}
}
Well, there are several methods for accessing ISessionFactory in statefull application (and a desktop application is that kind of application), among them:
Singleton
You could build the session factory once during the startup of your program and access it through a static singleton class.
This would force the application to use only one instance of the session factory.
example:
public sealed class NHibernateHelper
{
private static ISessionFactory SessionFactory;
private static readonly Configuration NhibernateConfig;
// ....
static NHibernateHelper()
{
NhibernateConfig = new Configuration().Configure();
SessionFactory = NhibernateConfig.BuildSessionFactory();
}
public static ISessionFactory GetSessionFactory()
{
return SessionFactory;
}
// ....
}
... and access the session factory through GetSessionFactory method all over the application.
Context Object and/or Dependency Injection
You could build the session factory from configuration and pass it through a context object all over the application.
example:
during startup:
// here you configure NHibernate.
ISessionFactory _sessionFactory = BuildMySessionFactory();
// ...
ObjectFactory.Initialize(x =>
{
x.For<IPatientRepository>()
.Use<StandardPatientRepository>()
.Ctor<ISessionFactory>().Is(_sessionFactory);
// ... initialize the rest of your repositories...
});
then:
public class StandardPatientRepository : IPatientRepository
{
private readonly ISessionFactory _sessionFactory;
public StandardPatientRepository(ISessionFactory sessionFactory)
{
if (sessionFactory == null)
throw new ArgumentNullException("sessionFactory");
_sessionFactory = sessionFactory;
}
public virtual Patient Get(Guid id)
{
using (IStatelessSession session =
_sessionFactory.OpenStatelessSession())
{
return session.Get<Patient>(id);
}
}
// the rest of data-access methods.
}
then in your classes that will make use of the data (ie. use the repositories) you will use:
Patient = ObjectFactory.GetInstance<IPatientRepository>().Get(patient);
In my opinion the second method is better as I think that singleton in most cases is an anti-pattern. The second approach will give you more control over your data layer, you will know who and when is accessing it.
Here is a well done and extensive sample application using NHibernate in a desktop application:
Building a Desktop To-Do Application with NHibernate
Managing the NHibernate session in a desktop application tends to be a lot more involved than managing the NHibernate session in a web application.

Resources