Use Spring Batch to write in different Data Sources - spring-batch

For a project I need to process items from one table and generate 3 different items for 3 different tables, all 3 in a second data source different from the one of the first item. The implementation is done with Spring Batch over Oracle DB. I think this question has something similar to what I need, but in there it is writing at the end only one different item.
To ilustrate the situation:
DataSource 1 DataSource 2
------------ ------------------------------
Table A Table B Table C Table D
The reader should read one item from table A. In the processor, using the information from the item in A, 3 new items will be created of type B, C and D. In addition, the item from table A will be updated.
The writer should be able to write at the same time all 4 items. My first implementation is using a JpaItemWriter to update the item A, but I don't know how the processor could give the other 3 items to the writer in order to save all at the same time.
Can a processor return several items from different types? Would I need to create 4 steps, each one writing one of the items? And in this case, would that be error safe (If there is an error writing D, then A, B, and C would be rollback)?
Thanks in advance for your support!

Your question is really two questions. Let's look at each individually:
Can an ItemProcessor return multiple items
An ItemProcessor can only return one item at a time for each item that is passed in. Because of this, in your specific scenario, you'll need your ItemProcessor to return a wrapper object that wraps items A, B, C, and D.
How can I write different types in the same step
Spring Batch relies heavily on composition in it's programming model. Since your ItemProcessor will be returning a wrapper object, you'll end up writing an ItemWriter that unwraps items A, B, C, and D and delegates the writing of each to the apropriate writer. So in the final solution, you'll end up with 5 ItemWriters: one for each item type and one that wraps all of those. Take a look at our CompositeItemWriter as an example here: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemWriter.java

Related

Creating decision tables in Red Hat Decision Central not reflecting complex types / structures

I have a DMN decision created in Decision Manager 7.3. I have a few data types created, all of which are "structures" (i.e. complex types) with nested fields. I have created a decision table of which the condition column is bound to one of these structures (Customer) and the output column is bound to a Result structure.
However, I would expect the column headers to reflect the structure of the objects as per the example here (step 9 onwards): https://access.redhat.com/documentation/en-us/red_hat_decision_manager/7.3/html-single/designing_a_decision_service_using_dmn_models/index#dmn-data-types-defining-proc_dmn-models
In the documentation example, the Loan_Qualification type has nested fields and these are shown as sub-columns in the table header.
My data types are defined as follows:
I have a Customer input node and a decision node defined as follows:
Yet in my decision table, the columns map to the top level object only as follows:
So any ideas as to what I might be missing? Thanks in advance.
UPDATE
I have used the answer given below by #karreiro which works for the outcome / action column, but inserting an Input Clause left or right adds a new top level column, not a sub column, which then looks like the following:
Is this something you expect the decision table editor to be able to do as well?
Your expectations are correct.
The DMN editor aims to support the auto-creation of fields for Structure Data Types (for output clauses https://issues.jboss.org/browse/DROOLS-3685, and input clauses https://issues.jboss.org/browse/DROOLS-4491).
However, momentarily, users need to create these fields manually:
See how to create here :-)

MATLAB- Joining tables w/ overlapping data using key variable WHERE neither table contains all data points from the other one

I am working on combining 2 tables with different types of patient information using the PID (Patient Identity) feature present in both tables. Usually the function "join" (https://www.mathworks.com/help/matlab/ref/table.join.html) does the trick when one of the tables have information on all the patients from the other one. But in my case, both tables have certain values of PID (or information for new patients) that isn't present in the other one. How do I create a new table for using patient info from both tables that only contains info on the patients present in both tables?
I could probably write some long, clunky code to do this manually, but I was wondering if there's a function (or a few functions) that can do the task more efficiently. Thank you
The solution is to use either innerjoin or outerjoin.

Pair Rx Sequences with one sequence as the master who controls when a new output is published

I'd like to pair two sequences D and A with Reactive Extensions in .NET. The resulting sequence R should pair D and A in a way that whenever new data appears on D, it is paired with the latest value from A as visualized in the following diagram:
D-1--2---3---4---
A---a------b-----
R----2---3---4---
a a b
CombineLatest or Zip does not exactly what I want. Any ideas on how this can be achieved?
Thanks!
You want Observable.MostRecent:
var R = A.Publish(_A => D.SkipUntil(_A).Zip(_A.MostRecent(default(char)), Tuple.Create));
Replace char with whatever the element type of your A observable.
Conceptually, the query above is the same as the following query.
var R = D.SkipUntil(A).Zip(A.MostRecent(default(char)), Tuple.Create));
The problem with this query is that subscribing to R subscribes to A twice. This is undesirable behavior. In the first (better) query above, Publish is used to avoid subscribing to A twice. It takes a mock of A, called _A, that you can subscribe to many times in the lambda passed to Publish, while only subscribing to the real observable A once.

How to perform multiple write from single item/line using Spring-Batch?

How can I perform multiple write from single item with the given data using spring-batch?
Do I need to read the input x times and create the object then write or read the input once and perform multiple write?
input:
id, label1, detail1, detail2, detail3
output1:
id, label1
output2:
id, detail1
id, detail2
id, detail3
Spring Batch provides a CompositeItemWriter that takes a list of ItemWriters. This writer calls each writer, in turn, with each item. So if I have an item that needs to be written to two different files in different formats, I can use the CompositeItemWriter to write each item to each file. In your case, you'd use multiple JdbcBatchItemWriters.
You can read more about the CompositeItemWriter in the documentation here: http://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/support/CompositeItemWriter.html
An example of this ItemWriter is shown in the Spring Batch samples here: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-samples/src/main/resources/jobs/compositeItemWriterSampleJob.xml

Postgres: n:m intermediate table with type

I have a table called "Tag" which consists of an Id, Name and Description column.
Now lets say I have the tables Character (C), Movie (M), Series (S) etc..
And I want to be able to tag entries in C, M, S with multiple tags and one tag may be used for multiple entries.
So I could realize it like this:
T -> TC <- C
T -> TM <- M
T -> TS <- S
Where TC, TM, TS are the intermediate tables.
I was wondering if I could combine TC, TM, TS into one table with a type column added and still use foreign keys.
As of yet I haven't found a way to do it.
Or is this something I shouldn't be doing?
As the comments above suggested you can't combine multiple table into a single one. If you want to have a single view of the "tag relationships" you can pull the needed information into a View. This way, you only need to write a longer query once and are able to use like a single table. Keep in mind that you can't insert data into a view (there are possibilities to do so, but they are a little advanced)