RequestContext.getCurrentInstance().update not rendering immediately - primefaces

I have a simple table [form:tabView:remTNtableID], with a list of strings CFSnumbers, and when I click a button I call getTelephoneNumbers() to fill it, which takes a while.
I'd like to have the table show "Loading.." while waiting, and for that purpose I cleared the list, added "Loading.." to the list, and called RequestContext.getCurrentInstance().update("form:tabView:remTNtableID").
But the table is not updated immediately, "Loading.." is not seen, and only when the getTelephoneNumbers() call ends is the table updated.
What's up? How can I force the table to be re-rendered immediately?
private List<String> CFSnumbers;
#PostConstruct
public void init() throws GuiException {
CFSnumbers = new ArrayList<String>();
}
public void getTelephoneNumbers() throws GuiException {
CFSnumbers.clear();
CFSnumbers.add("Loading..");
RequestContext.getCurrentInstance().update("form:tabView:remTNtableID");
try {
...
CFSnumbers = ...
RequestContext.getCurrentInstance().update("form:tabView:remTNtableID");
} catch (Exception e) {
CFSnumbers.clear();
RequestContext.getCurrentInstance().update("form:tabView:remTNtableID");
}

The action getTelephoneNumbers() is a single request. All updates are executed (send in the response) when your method has been fully executed.
What you could do is split your action into a reset part and a heavy loading part. When you click the button, call reset which resets and updates your table saying "Loading...". When the reset is completed, use a remoteCommand to start the actual heavy loading, and update the table when it completes.
So, in your XHTML:
<p:remoteCommand name="getTelephoneNumbersRemoteCommand"
action="#{yourBean.getTelephoneNumbers}"
update="remTNtableID"/>
<p:commandButton ...
action="#{yourBean.preGetTelephoneNumbers}"
update="remTNtableID"
oncomplete="getTelephoneNumbersRemoteCommand()"/>
And in your bean:
public void preGetTelephoneNumbers() {
CFSnumbers.clear();
CFSnumbers.add("Loading..");
}
public void getTelephoneNumbers() {
try {
...
CFSnumbers = ...
} catch (Exception e) {
CFSnumbers.clear();
}
}
Updating from your bean is no longer necessary, as it is done in the XHTML.
Related:
Is it safe to start a new thread in a JSF managed bean?

Related

How to unit test AsyncTask in android

Consider below code. How can I test this without using third party libraries? The Assert line is never executed, because it is a different thread and the vm stops running. Many thanks!
public class FileParserTask extends AsyncTask<File, Void, ArrayList<City>> {
private FileParserResult mResult;
public interface FileParserResult {
void onFinish(ArrayList<City> cities);
}
public FileParserTask(final FileParserResult result) {
mResult = result;
}
#Override
protected ArrayList<City> doInBackground(File... files) {
ArrayList<City> cities = new ArrayList<>();
try {
InputStream is = new FileInputStream(files[0]);
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginArray();
while (reader.hasNext()) {
City city = new Gson().fromJson(reader, City.class);
cities.add(city);
}
reader.endArray();
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
Collections.sort(cities, (o1, o2) -> o1.getName().compareTo(o2.getName()));
mResult.onFinish(cities);
return cities;
}
}
Test code:
#RunWith(AndroidJUnit4.class)
public class CityServiceTest {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "cities-medium.json");
#Test
public void givenInputAbuThenIShouldGetXResults() throws InterruptedException {
new FileParserTask(cities -> {
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
}).execute(file);
}
}
Although the code you need to test:
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
is being run in an AsyncTask, that's not really relevant to unit testing. AsyncTask has most likely been extensively tested by Google so you know that it will work as an AsyncTask. The real testing seems to be the functionality that needs to be run in the background, i.e. the business logic contained in doInBackground.
Thinking about it in terms of business logic, there is a need to populate an ArrayList<City> and propagate it to the app. Android prefers this to be done on a background thread and propagation can be handled by notifications etc, both of which have been tested and released as working by Google so you don't really need to include them in a unit test. How you populate ArrayList<City> is the real unit test.
AsyncTask would be relevant for an integration test but you'd most likely be testing a different aspect of the app for that, i.e. what it displays rather than what it receives from a background thread.
So for a unit test I'd refactor out the code in doInBackground so that it can be tested independently of how Android wants it to be run.
Sorry, did you override the onPostExecute method of the AsyncTask.
You are keeping the Result handler, but not using it anywhere.
#Override
protected void onPostExecute(Object result) {
mResult.processFinish(result);
}
As for the assertion it looks good to me as it is.
As you say, the problem is the AsyncTask running in a background thread, via an ExecutorService. Like with a Future though, it provides a get() method that will wait for, and return, the result.
new FileParserTask(cities -> {
Assert.assertEquals("Input should give back 200 results", 3, cities.size());
}).execute(file).get();

Mysql: disable autocommit with each insert in Spring

I'm using Spring 4.0.5, Mysql 5.6.19 and BoneCP 0.8.0
My issue is that, in one transaction defined in the application, MySql is commiting each insert or update, so it does not making a transaction.
First of all, I have read some questions like mine, but setting this in the Spring datasource does not work for me:
<property name="defaultAutoCommit" value="false" />
My classes are these:
DBWriter.java
private DataSourceTransactionManager txManager; // Injected in Spring Beans XML
private IMyDAO writerDAO;
public void saveBeans(DataContainer targetData) throws Throwable{
try {
JdbcTemplate templateTransaction = new JdbcTemplate(txManager.getDataSource());
MyTx newTx = new MyTx(targetData, templateTransaction, writerDAO);
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
txTemplate.execute(newTx);
} catch (Throwable e) {
logger.error("Error saving into DB", e);
throw e;
}
}
MyTx.java
public class MyTx extends TransactionCallbackWithoutResult {
private IMyDAO writerDAO;
private DataContainer finalData;
private JdbcTemplate txTemplate;
public MyTx(DataContainer newData, JdbcTemplate newTxTemplate, IMyDAO writerDAO){
this.finalData = newData;
this.txTemplate = newTxTemplate;
this.writerDAO = writerDAO;
}
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
writerDAO.saveTargetBean(newData, txTemplate);
}
}
MyDAO.java
private void saveTargetBean(...) {
jdbcTemplate.update("INSERT...", ...); // First
jdbcTemplate.update("INSERT...", ...); // Second
jdbcTemplate.update("INSERT...", ...); // Third
}
My issue is, when debugging step by step or forcing failures, First, Second, Thirs is committing immediately to database, without transactional behaviour.
Is there anything wrong in my code or in my approach? Should I put the INSERTs sentences directly in doInTransactionWithoutResult method? Should I do this in another way, so the three inserts were done in a transactional way?
Any help would be very very appreciated.
Regards
As Martin suggest, declarative transaction with #Transactional are better for this, and works for me. So, thank you
These two links were very helpful for me in this topic:
Propagation types
#Transactional example

Windows Phone - How to refresh viewmodel when navigating back

I have two ViewModels, the first has a list of type ProductViewModel, this list of type ProductViewModel is backed by a list of type Product in my model.
public List<ProductViewModel> Products
{
get
{
return (from product in ProductManager.Products
select new ProductViewModel(product)).ToList();
}
}
My first ViewModel will add products to the ProductManager.Products list and then raise a PropertyChanged notification so that the UI is updated. (So far so good).
A navigation to a second page then occurs, this then accesses the ProductManager.Products, once these products are processed, the ProductManager.Products list is cleared (by the second ViewModel).
Upon navigating back to the first view, how would I then update the List Products binding?
I am using the ViewModelLocator as provided by MVVMLight and therefore do not have static access to the first ViewModel from the second.
My current workaround is to create a BaseView page, override the OnNavigatedTo method, raise an event in this override, which I can then bind a Command to in my first ViewModel so that I can then call RaisePropertyChanged.
public class BaseView : PhoneApplicationPage
{
public event RoutedEventHandler NavigatedTo;
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (NavigatedTo != null)
{
NavigatedTo(this, new RoutedEventArgs());
}
}
}
<i:EventTrigger EventName="NavigatedTo">
<cmdextras:EventToCommand Command="{Binding Path=PerformNavigatedTo}" />
</i:EventTrigger>
public ICommand PerformNavigatedTo
{
get
{
return new RelayCommand(
() =>
{
RaisePropertyChanged(() => Products);
RaisePropertyChanged(() => SecondaryPageName);
},
() => true);
}
}
In addition to my workaround above, I previously investigated implementing messaging between ViewModels. Unfortunately this wasn't working for me as I had forgotten to include the Token when calling the Register method. As soon as I sorted this out I was able to send a message from the second ViewModel to be received by the first and therefore call the RaisePropertyChanged method as required.
Also, as soon as I realised that SimpleIoC returned the same instance after multiple calls to GetInstance, this helped in my understanding.

Exception not cuaght with Entity Manager

I have an Entity Manager in my EJB
#PersistenceContext(unitName = "cnsbEntities")
private EntityManager em;
I populate an object and then I commit it in my DB, but if I have an exception, for duplicate ID, I can't catch it and I don't know why.
try{
em.merge(boelLog);
} catch (Exception e){
System.out.println("Generic Exception");
}
JPA uses transactions to send entity modifications to the database. You can specify those transactions manually through Bean Managed Transactions (BMT) or let the application server do it for you (Container Managed Transactions; the default).
So, you need to catch the exception at the end of the transaction, and not after calling merge() or persist() methods of EntityManager class. In your case, probably the transaction will end when you return from the last EJB object.
Example for Container Managed Transactions (the default):
#Stateless
public class OneEjbClass {
#Inject
private MyPersistenceEJB persistenceEJB;
public void someMethod() {
try {
persistenceEJB.persistAnEntity();
} catch(PersistenceException e) {
// here you can catch persistence exceptions!
}
}
}
...
#Stateless
public class MyPersistenceEJB {
// this annotation forces application server to create a new
// transaction when calling this method, and to commit all
// modifications at the end of it!
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void persistAnEntity() {
// merge stuff with EntityManager
}
}
It's possible to specify when a method call (or any method call of an object of an EJB) must, can or must not create a new transaction. This is done through the #TransactionAttribute annotation. By default, every method of an EJB is configured as REQUIRED (same as specifying #TransactionAttribute(TransactionAttributeType.REQUIRED)), that tells the application to reuse (continue) the transaction that is active when that method was called, and create a new transaction if needed.
More about transactions here: http://docs.oracle.com/javaee/7/tutorial/doc/transactions.htm#BNCIH
More about JPA and JTA here: http://en.wikibooks.org/wiki/Java_Persistence/Transactions

How to force a SQLException in JUnit

I'm writing unit tests in JUnit, but have not been able to successfully cover a branch of a particular method that catches a SQLException and returns a null object.
This is the class I'm testing:
#Component
public class UnitOfMeasureRowMapper implements RowMapper<UnitOfMeasure> {
public UnitOfMeasure mapRow(final ResultSet resultSet, final int rowNumber) throws SQLException {
UnitOfMeasure unitOfMeasure = new UnitOfMeasure();
try {
unitOfMeasure.setUnitOfMeasureId(resultSet.getInt("UNITOFMEASUREID"));
unitOfMeasure.setOwnerUserId(resultSet.getInt("USERID"));
unitOfMeasure.setName(resultSet.getString("NAME"));
unitOfMeasure.setDescription(resultSet.getString("DESCRIPTION"));
} catch (SQLException e) {
unitOfMeasure = null;
}
return unitOfMeasure;
}
}
This is the JUnit test that I have written to cover the second branch of the above method (with appropriate context from the test class):
private static UnitOfMeasure testUnitOfMeasure;
private static UnitOfMeasureRowMapper mockRowMapper;
public void setUp() throws Exception {
mockRowMapper = mock(UnitOfMeasureRowMapper.class);
mockResultSet = mock(ResultSet.class);
}
#Test(expected=SQLException.class)
public void testUnitOfMeasureRowMapperFailsSQLException() throws SQLException {
when(mockRowMapper.mapRow(mockResultSet, 1)).thenReturn(null);
testUnitOfMeasure = mockRowMapper.mapRow(mockResultSet, 1);
}
I think the problem is with the last line; somehow I need to force a SQLException. The problem is, I don't know how and haven't been able to find an answer. Can anyone help?
If I understand the question well, the class under test is UnitOfMeasureRowMapper. If this is true, then you don't want to mock it in your test, otherwise you are testing a mock!
What is under test in your JUnit, is the behavior of UnitOfMeasureRowMapper#mapRow when ResultSet you give it throws a SQLException during the execution of the method. Then you want this method to return null.
I would write it like this:
private ResultSet mockResultSet;
private RowMapper<UnitOfMeasure> rowMapper = new UnitOfMeasureRowMapper();
public void setUp() throws Exception {
mockResultSet = mock(ResultSet.class);
}
#Test
public void mapRow_SHOULD_return_null_WHEN_resultSet_throws_a_SQLException() {
when(mockResultSet.getInt(anyString()).thenThrow(new SQLException());
assertThat(mockRowMapper.mapRow(mockResultSet, 1), nullValue());
}
As suggested Samuel in his answer, you may set one of the method of the result set you use to throw a SQLException, and then check in your JUnit that the mapRow method returns null as expected. Here you are not testing the behavior of the result set, so its fine to mock it to achieve a behavior it would normally have under some circunstancies that would be painful to obtain otherwise. Mocking the result set behavior lets you focus on testing the RowMapper behavior.
You are testing the UnitOfMeasureRowMapper that implements RowMapper. So have a rowMapper property in your JUnit, and I prefer to see it through its interface. I like to brutally call the constructor of UnitOfMeasureRowMapper because I want to keep my JUnit as simple as they can be.
Set one of the methods (maybe getInt?) of your mock ResultSet to throw the exception. You didn't specify what mocking framework you're using so I can't tell you the exact syntax.