Discussion:
JPA component - Persist 1 record working but how to persist many records?
r***@public.gmane.org
2013-10-27 01:55:33 UTC
Permalink
Hi guys,

Fairly new to Apache Camel. I have a Camel program which parses some XML
using Jaxb and then inserts the parsed objects into the database using open
JPA. The example is very similar to the Camel ETL example. At the moment I
have the application persisting records from the XML however it is only
persisting the first record!

I'm looking for some advice on how to change the application so that it
inserts all parsed objects (all items in my case).

My item XML looks like this...

<?xml version="1.0" encoding="UTF-8"?>
<WEB-ITM-EXT-FIL>
<WEB-ITM-EXT-REC>
<WEB-ITM-EXT-DATA>
<ITEM-NO>93501250080</ITEM-NO>
<DESCRIPTION>KHOMBU APFOOTA KOKO HIGH</DESCRIPTION>
</WEB-ITM-EXT-DATA>
</WEB-ITM-EXT-REC>
<WEB-ITM-EXT-REC>
<WEB-ITM-EXT-DATA>
<ITEM-NO>93501250090</ITEM-NO>
<DESCRIPTION>TEST</DESCRIPTION>
</WEB-ITM-EXT-DATA>
</WEB-ITM-EXT-REC>
</WEB-ITM-EXT-FIL>

Here is what my route looks like...

from("file:src/data?fileName=FIT.XML&noop=true")
.convertBodyTo(ItemRootDocument.class)
.split().method(ItemDocumentService.class,
"splitItemsDocuments")
.log("Split line ${body}")
.to("jpa:org.apache.camel.example.etl.ItemEntity");

Here is my Split...

public List<ItemDocument> splitItemsDocuments(ItemRootDocument doc) {
ItemDocuments itemDocuments = doc.getItemDocumentsList().get(0);
return itemDocuments.getItemDocumentList();
}

And my ItemTransformer to convert to an ItemEntity looks like this...

public class ItemTransformer {

@Converter
public ItemEntity toItem(ItemDocument doc, Exchange exchange)
throws Exception {
JpaTemplate template =
exchange.getIn().getHeader("CamelJpaTemplate", JpaTemplate.class);
String itemNo = doc.getItemNo();
ItemEntity item = new ItemEntity();
item.setItemNo(itemNo);
item.setDescription(doc.getDescription());
return item;
}

So it splits the Items in the XML document and persists but only persists
the first one. How would I change this so that all parsed items are split?
Thanks
r***@public.gmane.org
2013-10-27 06:04:19 UTC
Permalink
Hi All,

Well I spent a few hours on this today trying to understand how to do this.
What I did was to change my splitter to do this...

public List<ItemDocuments> splitItemsRootDocuments(ItemRootDocument doc) {
List<ItemDocuments> itemDocuments = doc.getItemDocumentsList();
return itemDocuments;
}

It returns both items 93501250080 and 93501250090.

Then I changed my converter...

public class ItemTransformer {
@Converter
public ItemEntity toItem(ItemDocuments docs, Exchange exchange)
throws Exception {
JpaTemplate template =
exchange.getIn().getHeader("CamelJpaTemplate", JpaTemplate.class);
List<ItemEntity> items = new ArrayList<ItemEntity>();
List itemDocs = docs.getItemDocumentList();
for (Iterator i = itemDocs.iterator(); i.hasNext();){
ItemDocument doc = (ItemDocument)i.next();
String itemNo = doc.getItemNo();
ItemEntity item = new ItemEntity();
item.setItemNo(itemNo);
item.setDescription(doc.getDescription());
}
return items;
}

to return a list of ItemEntity's. (i.e. not just the one). Does this seem
like the right approach. I thinking it is.

The only error I have now is ...

No type converter available to convert from type:
org.apache.camel.example.etl.ItemDocuments to the required type:
org.apache.camel.example.etl.ItemEntity

Because I'm now returning a list of ItemEntity objects instead of just the
single one. I don't know how to fix this yet but will try to find out.

Comments to tell me if I am heading down the right track would be much
appreciated.

thanks
Babak Vahdat
2013-10-27 09:35:22 UTC
Permalink
Hi

See the documentation about how to pass over more than one single JPA entity
objects to the producer:
http://camel.apache.org/jpa#JPA-Sendingtotheendpoint

Babak
Post by r***@public.gmane.org
Hi All,
Well I spent a few hours on this today trying to understand how to do
this. What I did was to change my splitter to do this...
public List
<ItemDocuments>
splitItemsRootDocuments(ItemRootDocument doc) {
List
<ItemDocuments>
itemDocuments = doc.getItemDocumentsList();
return itemDocuments;
}
It returns both items 93501250080 and 93501250090.
Then I changed my converter...
public class ItemTransformer {
@Converter
public ItemEntity toItem(ItemDocuments docs, Exchange exchange)
throws Exception {
JpaTemplate template =
exchange.getIn().getHeader("CamelJpaTemplate", JpaTemplate.class);
List
<ItemEntity>
items = new ArrayList
<ItemEntity>
();
List itemDocs = docs.getItemDocumentList();
for (Iterator i = itemDocs.iterator(); i.hasNext();){
ItemDocument doc = (ItemDocument)i.next();
String itemNo = doc.getItemNo();
ItemEntity item = new ItemEntity();
item.setItemNo(itemNo);
item.setDescription(doc.getDescription());
}
return items;
}
to return a list of ItemEntity's. (i.e. not just the one). Does this seem
like the right approach. I thinking it is.
The only error I have now is ...
org.apache.camel.example.etl.ItemEntity
Because I'm now returning a list of ItemEntity objects instead of just the
single one. I don't know how to fix this yet but will try to find out.
Comments to tell me if I am heading down the right track would be much
appreciated.
thanks
Taariq Levack
2013-10-27 09:47:20 UTC
Permalink
Hi
I think you're getting there, the splitter should return all the items, but the converter should convert a single ItemDocument to an entity.
Maybe also change the splitter signature to public List<ItemDocument>

Taariq
Post by r***@public.gmane.org
Hi All,
Well I spent a few hours on this today trying to understand how to do this.
What I did was to change my splitter to do this...
public List<ItemDocuments> splitItemsRootDocuments(ItemRootDocument doc) {
List<ItemDocuments> itemDocuments = doc.getItemDocumentsList();
return itemDocuments;
}
It returns both items 93501250080 and 93501250090.
Then I changed my converter...
public class ItemTransformer {
@Converter
public ItemEntity toItem(ItemDocuments docs, Exchange exchange)
throws Exception {
JpaTemplate template =
exchange.getIn().getHeader("CamelJpaTemplate", JpaTemplate.class);
List<ItemEntity> items = new ArrayList<ItemEntity>();
List itemDocs = docs.getItemDocumentList();
for (Iterator i = itemDocs.iterator(); i.hasNext();){
ItemDocument doc = (ItemDocument)i.next();
String itemNo = doc.getItemNo();
ItemEntity item = new ItemEntity();
item.setItemNo(itemNo);
item.setDescription(doc.getDescription());
}
return items;
}
to return a list of ItemEntity's. (i.e. not just the one). Does this seem
like the right approach. I thinking it is.
The only error I have now is ...
org.apache.camel.example.etl.ItemEntity
Because I'm now returning a list of ItemEntity objects instead of just the
single one. I don't know how to fix this yet but will try to find out.
Comments to tell me if I am heading down the right track would be much
appreciated.
thanks
--
View this message in context: http://camel.465427.n5.nabble.com/JPA-component-Persist-1-record-working-but-how-to-persist-many-records-tp5742267p5742269.html
Sent from the Camel - Users mailing list archive at Nabble.com.
r***@public.gmane.org
2013-10-27 10:31:20 UTC
Permalink
Thank you so much Taariq,

Your advice was exactly what I needed to give me enough information to
resolve my issue.

public List<ItemDocument> splitItemsRootDocuments(ItemRootDocument doc) {
List<ItemDocument> items = new ArrayList();
List<ItemDocuments> itemDocumentsList = doc.getItemDocumentsList();
for (ItemDocuments itemDocuments : itemDocumentsList) {
items.addAll(itemDocuments.getItemDocumentList());
}
return items;
}


regards
Taariq Levack
2013-10-27 11:47:28 UTC
Permalink
Great, glad its solved.
I only saw Babak's comment now and didn't think of it earlier. The component will also take a collection of entities, so no need to split, just convert.
You now have another tool in the box though, enjoy the ride.
Post by r***@public.gmane.org
Thank you so much Taariq,
Your advice was exactly what I needed to give me enough information to
resolve my issue.
public List<ItemDocument> splitItemsRootDocuments(ItemRootDocument doc) {
List<ItemDocument> items = new ArrayList();
List<ItemDocuments> itemDocumentsList = doc.getItemDocumentsList();
for (ItemDocuments itemDocuments : itemDocumentsList) {
items.addAll(itemDocuments.getItemDocumentList());
}
return items;
}
regards
--
View this message in context: http://camel.465427.n5.nabble.com/JPA-component-Persist-1-record-working-but-how-to-persist-many-records-tp5742267p5742278.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Loading...