You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Chris Wolf <cw...@gmail.com> on 2013/01/16 01:07:35 UTC

Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

It was me not RTFM more carefully.  Sorry about that.  On the main
Camel-JPA page it mentions a query option
called "consumer.resultClass" which can be used to define the result
class for a native query.  So when I added that,
it all worked.

Otherwise, without "consumer.resultClass", the native query returns
List<Object[]>.

But here's the thing - if I'm already indicating the entity class in
the "scheme-specific-part" of the URI, (or entityType option)
then why must it be specified again?  Seems redundant and I think
seeing it there lulled me into thinking that the return
type was defined, even for a native query.

Thanks again,

    -Chris

On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf <cw...@gmail.com> wrote:
> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>
>
>
> Here's the route, followed by console output, followed by entities
> code.  BTW, I notice that the data type of Body coming out
> of the jpa endpoint is of type Object[], I think this is part of the
> problem, because I put a breakpoint on line 159 in JpaConsumer,
> which is:
>
> getDeleteHandler().deleteObject(entityManager, result);
>
> ...and that  "result" is of type Object[] where each element is a
> field value of the entity cooresponding to the
> MarketData entity but it's NOT of type MarketData - hence the cast
> exception when EntityManager.remove() is called.
>
> Thanks Claus and Christian,
>
>     -Chris
>
>
>
>
>
> from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelete=true&consumer.nativeQuery=select
> * from market_data where rownum < 10")
>                 .to("log:test.camel?showAll=true&multiline=true&level=INFO")
>                 .to("mock:foo");
>
> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary class
> "org.apache.openjpa.jdbc.sql.OracleDictionary".
> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
> test.camel - Exchange[
> , Id:ID-cwolf-55710-1358279796309-0-2
> , ExchangePattern:InOnly
> , Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=true&showAll=true,
> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
> , Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e99db4,
> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
> , BodyType:Object[]
> , Body:[Ljava.lang.Object;@a1e2da
> , Out: null
> ]
> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
> org.apache.camel.component.jpa.JpaConsumer - Error processing last
> message due: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
> Ensure that it has been enhanced.
> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
> successful processed message, and ignore this last failure.
> javax.persistence.PersistenceException: <openjpa-2.2.1-r422266:1396819
> nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
> PersistenceCapable failed.  Ensure that it has been enhanced.
> FailedObject: [Ljava.lang.Object;@1cfd3b2
>         at org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:102)
>         at org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doInJpa(JpaTemplateTransactionStrategy.java:82)
>         at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>         at org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>         at org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInTransaction(JpaTemplateTransactionStrategy.java:80)
>         at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
>         at org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(JpaTemplateTransactionStrategy.java:78)
>         at org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>         at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:139)
>         at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:91)
>         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>         at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
>         at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
>         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
>         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
>         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>         at java.lang.Thread.run(Thread.java:662)
> Caused by: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
> Ensure that it has been enhanced.
> FailedObject: [Ljava.lang.Object;@1cfd3b2
>         at org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.java:4667)
>         at org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java:2683)
>         at org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>         at org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>         at org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.java:1102)
>         at org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManagerImpl.java:730)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:597)
>         at org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHandler.invoke(JpaTemplate.java:425)
>         at $Proxy14.remove(Unknown Source)
>         at org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer.java:337)
>         at org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:159)
>         at org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:97)
>         ... 18 more
>
>
> Here is the parent entity (which has collection of child entities)
>
> package entities;
>
> import java.io.Serializable;
> import javax.persistence.*;
> import java.math.BigDecimal;
> import java.util.Date;
> import java.util.Set;
>
>
> /**
>  * The persistent class for the MARKET_DATA database table.
>  *
>  */
> @Entity
> @Table(name="MARKET_DATA")
> public class MarketData implements Serializable {
>         private static final long serialVersionUID = 1L;
>         private long marketDataId;
>         private String currencyCode;
>         private Date dataDate;
>         private BigDecimal lastPrice;
>         private BigDecimal lastUpdatedPrice;
>         private String name;
>         private String requestId;
>         private String requestIdType;
>         private String subType;
>         private String type;
>         private String vendorId;
>         private String vendorName;
>         private Set<RiskFactor> riskFactors;
>
>     public MarketData() {
>     }
>
>
>         @Id
>         @SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
> sequenceName="MARKET_DATA_ID_SEQ")
>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false, precision=19)
>         public long getMarketDataId() {
>                 return this.marketDataId;
>         }
>
>         public void setMarketDataId(long marketDataId) {
>                 this.marketDataId = marketDataId;
>         }
>
>
>         @Column(name="CURRENCY_CODE", length=3)
>         public String getCurrencyCode() {
>                 return this.currencyCode;
>         }
>
>         public void setCurrencyCode(String currencyCode) {
>                 this.currencyCode = currencyCode;
>         }
>
>
>     @Temporal( TemporalType.DATE)
>         @Column(name="DATA_DATE")
>         public Date getDataDate() {
>                 return this.dataDate;
>         }
>
>         public void setDataDate(Date dataDate) {
>                 this.dataDate = dataDate;
>         }
>
>
>         @Column(name="LAST_PRICE", precision=20, scale=4)
>         public BigDecimal getLastPrice() {
>                 return this.lastPrice;
>         }
>
>         public void setLastPrice(BigDecimal lastPrice) {
>                 this.lastPrice = lastPrice;
>         }
>
>
>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>         public BigDecimal getLastUpdatedPrice() {
>                 return this.lastUpdatedPrice;
>         }
>
>         public void setLastUpdatedPrice(BigDecimal lastUpdatedPrice) {
>                 this.lastUpdatedPrice = lastUpdatedPrice;
>         }
>
>
>         @Column(length=100)
>         public String getName() {
>                 return this.name;
>         }
>
>         public void setName(String name) {
>                 this.name = name;
>         }
>
>
>         @Column(name="REQUEST_ID", length=50)
>         public String getRequestId() {
>                 return this.requestId;
>         }
>
>         public void setRequestId(String requestId) {
>                 this.requestId = requestId;
>         }
>
>
>         @Column(name="REQUEST_ID_TYPE", length=20)
>         public String getRequestIdType() {
>                 return this.requestIdType;
>         }
>
>         public void setRequestIdType(String requestIdType) {
>                 this.requestIdType = requestIdType;
>         }
>
>
>         @Column(name="SUB_TYPE", length=100)
>         public String getSubType() {
>                 return this.subType;
>         }
>
>         public void setSubType(String subType) {
>                 this.subType = subType;
>         }
>
>
>         @Column(name="\"TYPE\"", length=100)
>         public String getType() {
>                 return this.type;
>         }
>
>         public void setType(String type) {
>                 this.type = type;
>         }
>
>
>         @Column(name="VENDOR_ID", length=50)
>         public String getVendorId() {
>                 return this.vendorId;
>         }
>
>         public void setVendorId(String vendorId) {
>                 this.vendorId = vendorId;
>         }
>
>
>         @Column(name="VENDOR_NAME", length=100)
>         public String getVendorName() {
>                 return this.vendorName;
>         }
>
>         public void setVendorName(String vendorName) {
>                 this.vendorName = vendorName;
>         }
>
>
>         //bi-directional many-to-many association to RiskFactor
>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
> CascadeType.REFRESH})
>         @JoinTable(
>                 name="MARKET_DATA_RISK_FACTOR"
>                 , joinColumns={
>                         @JoinColumn(name="MARKET_DATA_ID", nullable=false)
>                         }
>                 , inverseJoinColumns={
>                         @JoinColumn(name="RISK_FACTOR_ID", nullable=false)
>                         }
>                 )
>         public Set<RiskFactor> getRiskFactors() {
>                 return this.riskFactors;
>         }
>
>         public void setRiskFactors(Set<RiskFactor> riskFactors) {
>                 this.riskFactors = riskFactors;
>         }
> }
>
>
>
> package entities;
>
> import java.io.Serializable;
> import javax.persistence.*;
> import java.math.BigDecimal;
> import java.util.Date;
> import java.util.Set;
>
>
> /**
>  * The persistent class for the RISK_FACTOR database table.
>  *
>  */
> @Entity
> @Table(name="RISK_FACTOR")
> public class RiskFactor implements Serializable {
>         private static final long serialVersionUID = 1L;
>         private long riskFactorId;
>         private Date dataDate;
>         private String name;
>         private BigDecimal seq;
>         private BigDecimal seq2;
>         private String type;
>         private BigDecimal value;
>         private BigDecimal value2;
>         private Set<MarketData> marketData;
>
>     public RiskFactor() {
>     }
>
>
>         @Id
>         @SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
> sequenceName="RISK_FACTOR_ID_SEQ")
>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false, precision=19)
>         public long getRiskFactorId() {
>                 return this.riskFactorId;
>         }
>
>         public void setRiskFactorId(long riskFactorId) {
>                 this.riskFactorId = riskFactorId;
>         }
>
>
>     @Temporal( TemporalType.DATE)
>         @Column(name="DATA_DATE")
>         public Date getDataDate() {
>                 return this.dataDate;
>         }
>
>         public void setDataDate(Date dataDate) {
>                 this.dataDate = dataDate;
>         }
>
>
>         @Column(length=100)
>         public String getName() {
>                 return this.name;
>         }
>
>         public void setName(String name) {
>                 this.name = name;
>         }
>
>
>         @Column(precision=1)
>         public BigDecimal getSeq() {
>                 return this.seq;
>         }
>
>         public void setSeq(BigDecimal seq) {
>                 this.seq = seq;
>         }
>
>
>         public BigDecimal getSeq2() {
>                 return this.seq2;
>         }
>
>         public void setSeq2(BigDecimal seq2) {
>                 this.seq2 = seq2;
>         }
>
>
>         @Column(name="\"TYPE\"", length=100)
>         public String getType() {
>                 return this.type;
>         }
>
>         public void setType(String type) {
>                 this.type = type;
>         }
>
>
>         @Column(name="\"VALUE\"", precision=20, scale=4)
>         public BigDecimal getValue() {
>                 return this.value;
>         }
>
>         public void setValue(BigDecimal value) {
>                 this.value = value;
>         }
>
>
>         @Column(precision=20, scale=4)
>         public BigDecimal getValue2() {
>                 return this.value2;
>         }
>
>         public void setValue2(BigDecimal value2) {
>                 this.value2 = value2;
>         }
>
>
>         //bi-directional many-to-many association to MarketData
>         @ManyToMany(mappedBy="riskFactors")
>         public Set<MarketData> getMarketData() {
>                 return this.marketData;
>         }
>
>         public void setMarketData(Set<MarketData> marketData) {
>                 this.marketData = marketData;
>         }
>
> }
> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
> <ch...@gmail.com> wrote:
>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which you are
>> using. Can you upgrade?
>>
>> Best,
>> Christian
>>
>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf <cw...@gmail.com> wrote:
>>
>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>> query.  If I have consumeDelete=false configured,
>>> then it works and I see the entities.  When consumeDelete=false is not
>>> configured (default is to remove), then the error
>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) - but
>>> "arg" is of type Object[] - not the entity.
>>>
>>> Second issue is I'd like the route to just perform the query once.
>>> As it is, invokes the query in a loop.
>>>
>>> Thanks
>>>
>>> Chris
>>>
>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>> entities not being enhanced - I verified that with javap.
>>>
>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all previous

Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

Posted by Babak Vahdat <ba...@swissonline.ch>.

Am 16.01.13 18:17 schrieb "Chris Wolf" unter <cw...@gmail.com>:

>Babak,
>
>Thanks again for the reply.  I just wanted to mention that I think the
>jpa component is
>totally fine and usable as it is, and Camel, as a whole, is an awesome
>framework.
>
>However, I do have some remarks to make concerning the URI format for
>jpa, you may
>not agree, but I'd like to just make these remarks in closing on this
>issue.
>(of course, feel free to reply, I'm just saying I don't you to feel
>you have to.)
>
>On Wed, Jan 16, 2013 at 8:53 AM, Babak Vahdat
><ba...@swissonline.ch> wrote:
>> Yes I see your point but this is simply how the current codebase seems
>>like,
>> that's using
>>
>>   EntityManager.createNativeQuery(nativeQuery);
>>
>> is the *default* and if you want your entity object as the returned
>>value
>> then you have to *explicitly* ask for it. Changing this behaviour the
>>way
>> you ask for would break the existing applications relying on this
>>behaviour.
>
> But in spite of what the documentation says:
>
>    jpa:[entityClassName][?options]
>    For consuming, the entityClassName is mandatory.
>
>I find that "entityClassName" *can* be omitted in a jpa consumer and
>you will get back
>List<Object[]>, which is reasonable and expected.   However, if I
>specify  "entityClassName"
>I would expect the JpaComponent to return the results as a list of
>those entities, which
>it does not, but *could*, if the code were changed.
>
>> IMHO it's also "clean" & "good" the way it is already is by the current
>> camel-jpa codebase because if you look at the following three possible
>> method signatures JPA EntityManager API provides for the native query:
>>
>>   Query createNativeQuery(java.lang.String sqlString)
>>
>>   Query createNativeQuery(java.lang.String sqlString, java.lang.Class
>> resultClass)
>>
>>   Query createNativeQuery(java.lang.String sqlString, java.lang.String
>> resultSetMapping)
>
>This talk of the underlying EntityManager API is an implementation
>detail - as a user
>of the JPA component, I am only interested in the semantics of the URI
>format and
>options - I should not have to care about implementation details.
>
>Having said that - if I specify an entity class in the URI, I would
>expect the component
>to do whatever needs to be done to populate the result set into such
>entities.
>>
>> Then it makes sense that Camel defaults to the first one having *one*
>>single
>> parameter, as given one parameter that's also what JPA itself defaults
>>to as
>> well, that is per default it returns you List<Object[]> in case you
>>don't
>> ask for anything extra!
>
>Yes, but only if you don't specify entity class anywhere in the URI -
>not in scheme-part,
>not as "entityType" query option and not as "consumer.resultClass", on
>in that case
>should it return  List<Object[]>.
>
>As I said, it's perfectly usable as-is - I only nit-pick because I was
>initially confused.
>Also if you have "entityType", I would expect the other option to be
>consistently named,
>i.e. "consumer.entityType", not "consumer.resultClass" -  or the other
>way - around, but
>I think "consumer.resultClass" is superfluous anyway since you should
>only need to
>specify the entity type *once* in the URI.
>
>Anyway, you may not agree and that's fine, but at minimum, I would
>make small changes to
>the documentation:
>
>1.) It says that for consumers the "entityTypeClassName" (immediately
>following "jpa:")
>     is mandatory, but I find that it is not - the endpoint still
>queries the data.  I'm glad,
>     because for a nativeQuery where List<Object[]> is expected, this
>makes it more
>     clear by not mentioning entity type anywhere in the URI.  For a
>regular JPQL
>     (consumer.query), it *will* return the results as entities, even
>without
>     specifying the entity class *anywhere* in the URI.
>
>     So I would remove the statement that says "entityTypeClassName is
>mandatory" and
>     and please, don't change the code to make it mandatory for the
>case of List<Object[]>
>     results.
>
>
>2.) In the options table, the row where "consumer.resultClass" is
>documented, in the remarks
>    column, I would add to the note that mentions without this option,
>the results are List<Object[]>
>    - add to that: that in this case, consumeDelete=true will not work
>and will cause a cast exception
>    due to attempting to cast Object[] to PersistanceCapable.
>

There're tons of possible improvements/completions/corrections of the
Camel documentation at Apache, so why not just join the fun and help us to
improve it as you already suggested?

http://camel.apache.org/contributing.html

Also the Camel 3.0 roadmap is still open and nothing is
committed/confirmed as it says here:

http://camel.apache.org/camel-30-roadmap.html

So that everybody can come up with cool ideas @ the Camel dev forum,
discuss about them and dedicate his latest & greatest piece of software to
the community.


Babak


>
>Thanks for listening,
>
>Chris
>
>>
>> BTW currently the third variant is not supported at all.
>>
>> Babak
>>
>>
>> Chris Wolf wrote
>>> On Tue, Jan 15, 2013 at 9:11 PM, Babak Vahdat
>>> &lt;
>>
>>> babak.vahdat@
>>
>>> &gt; wrote:
>>>>
>>>>
>>>> Am 16.01.13 01:07 schrieb "Chris Wolf" unter &lt;
>>
>>> cwolf.algo@
>>
>>> &gt;:
>>>>
>>>>>It was me not RTFM more carefully.  Sorry about that.  On the main
>>>>>Camel-JPA page it mentions a query option
>>>>>called "consumer.resultClass" which can be used to define the result
>>>>>class for a native query.  So when I added that,
>>>>>it all worked.
>>>>>
>>>>>Otherwise, without "consumer.resultClass", the native query returns
>>>>>List&lt;Object[]&gt;.
>>>>>
>>>>>But here's the thing - if I'm already indicating the entity class in
>>>>>the "scheme-specific-part" of the URI, (or entityType option)
>>>>>then why must it be specified again?  Seems redundant and I think
>>>>>seeing it there lulled me into thinking that the return
>>>>>type was defined, even for a native query.
>>>>
>>>> It was my bad to not read through the thread before replying but
>>>>happy to
>>>> see you found the solution by yourself.
>>>>
>>>> Regarding your question why you should "repeat" yourself using the
>>>> "consumer.resultClass" option, well without using that option the
>>>> JpaConsumer makes use of:
>>>>
>>>>   EntityManager.createNativeQuery(nativeQuery);
>>>>
>>>> Which it's returned Query execution delivers List&lt;Object[]&gt; (See
>>>> JPA 2
>>>> spec. 3.8.6), however with that option being specified it makes use
>>>>of:
>>>>
>>>>   EntityManager.createNativeQuery(nativeQuery, myEntityClass);
>>>>
>>>> API which then returns List
>>> <myEntityClass>
>>> . So the reason is the way how
>>>> the native queries by the JPA API itself works.
>>>
>>> Right, but what I'm saying is that the JpaComponent already knows the
>>> entity type from the "scheme-specific-part" of the URI,
>>> i.e. "jpa:mypackage.myclass?bla,bla.."  - so why can't the
>>> JpaComponent use that to invoke
>>>  EntityManager.createNativeQuery(String, Class<?>)   ?
>>>
>>>
>>>>
>>>> Babak
>>>>
>>>>
>>>>>
>>>>>Thanks again,
>>>>>
>>>>>    -Chris
>>>>>
>>>>>On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf &lt;
>>
>>> cwolf.algo@
>>
>>> &gt; wrote:
>>>>>> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>>>>>>
>>>>>>
>>>>>>
>>>>>> Here's the route, followed by console output, followed by entities
>>>>>> code.  BTW, I notice that the data type of Body coming out
>>>>>> of the jpa endpoint is of type Object[], I think this is part of the
>>>>>> problem, because I put a breakpoint on line 159 in JpaConsumer,
>>>>>> which is:
>>>>>>
>>>>>> getDeleteHandler().deleteObject(entityManager, result);
>>>>>>
>>>>>> ...and that  "result" is of type Object[] where each element is a
>>>>>> field value of the entity cooresponding to the
>>>>>> MarketData entity but it's NOT of type MarketData - hence the cast
>>>>>> exception when EntityManager.remove() is called.
>>>>>>
>>>>>> Thanks Claus and Christian,
>>>>>>
>>>>>>     -Chris
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelet
>>>>>>e=tr
>>>>>>ue&consumer.nativeQuery=select
>>>>>> * from market_data where rownum < 10")
>>>>>>
>>>>>>.to("log:test.camel?showAll=true&multiline=true&level=INFO")
>>>>>>                 .to("mock:foo");
>>>>>>
>>>>>> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>>>> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
>>>>>> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>>>> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary
>>>>>>class
>>>>>> "org.apache.openjpa.jdbc.sql.OracleDictionary".
>>>>>> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
>>>>>> test.camel - Exchange[
>>>>>> , Id:ID-cwolf-55710-1358279796309-0-2
>>>>>> , ExchangePattern:InOnly
>>>>>> ,
>>>>>>Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=tru
>>>>>>e&sh
>>>>>>owAll=true,
>>>>>> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
>>>>>> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
>>>>>> ,
>>>>>>Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e9
>>>>>>9db4
>>>>>>,
>>>>>> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
>>>>>> , BodyType:Object[]
>>>>>> , Body:[Ljava.lang.Object;@a1e2da
>>>>>> , Out: null
>>>>>> ]
>>>>>> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
>>>>>> org.apache.camel.component.jpa.JpaConsumer - Error processing last
>>>>>> message due:
>>> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>>>> Ensure that it has been enhanced.
>>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
>>>>>> successful processed message, and ignore this last failure.
>>>>>> javax.persistence.PersistenceException:
>>> <openjpa-2.2.1-r422266:1396819
>>>>
>>>>> nonfatal user error>
>>>>>org.apache.openjpa.persistence.ArgumentException:
>>>>>> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
>>>>>> PersistenceCapable failed.  Ensure that it has been enhanced.
>>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java
>>>>>>:102
>>>>>>)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doI
>>>>>>nJpa
>>>>>>(JpaTemplateTransactionStrategy.java:82)
>>>>>>         at
>>>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>>>>>>         at
>>>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInT
>>>>>>rans
>>>>>>action(JpaTemplateTransactionStrategy.java:80)
>>>>>>         at
>>>>>>org.springframework.transaction.support.TransactionTemplate.execute(T
>>>>>>rans
>>>>>>actionTemplate.java:130)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute
>>>>>>(Jpa
>>>>>>TemplateTransactionStrategy.java:78)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>>>>>>         at
>>>>>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsum
>>>>>>er.j
>>>>>>ava:139)
>>>>>>         at
>>>>>>org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer
>>>>>>.jav
>>>>>>a:91)
>>>>>>         at
>>>>>>java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:44
>>>>>>1)
>>>>>>         at
>>>>>>java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java
>>>>>>:317
>>>>>>)
>>>>>>         at
>>>>>>java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>>>>>>         at
>>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.
>>>>>>acce
>>>>>>ss$101(ScheduledThreadPoolExecutor.java:98)
>>>>>>         at
>>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.
>>>>>>runP
>>>>>>eriodic(ScheduledThreadPoolExecutor.java:180)
>>>>>>         at
>>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.
>>>>>>run(
>>>>>>ScheduledThreadPoolExecutor.java:204)
>>>>>>         at
>>>>>>java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec
>>>>>>utor
>>>>>>.java:886)
>>>>>>         at
>>>>>>java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
>>>>>>.jav
>>>>>>a:908)
>>>>>>         at java.lang.Thread.run(Thread.java:662)
>>>>>> Caused by:
>>> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>>>> Ensure that it has been enhanced.
>>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>>>         at
>>>>>>org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerI
>>>>>>mpl.
>>>>>>java:4667)
>>>>>>         at
>>>>>>org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java
>>>>>>:268
>>>>>>3)
>>>>>>         at
>>>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>>>>>>         at
>>>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>>>>>>         at
>>>>>>org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.ja
>>>>>>va:1
>>>>>>102)
>>>>>>         at
>>>>>>org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManager
>>>>>>Impl
>>>>>>.java:730)
>>>>>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>>>>>>Method)
>>>>>>         at
>>>>>>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
>>>>>>java
>>>>>>:39)
>>>>>>         at
>>>>>>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
>>>>>>sorI
>>>>>>mpl.java:25)
>>>>>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>>>>>         at
>>>>>>org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHan
>>>>>>dler
>>>>>>.invoke(JpaTemplate.java:425)
>>>>>>         at $Proxy14.remove(Unknown Source)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer
>>>>>>.jav
>>>>>>a:337)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.j
>>>>>>ava:
>>>>>>159)
>>>>>>         at
>>>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java
>>>>>>:97)
>>>>>>         ... 18 more
>>>>>>
>>>>>>
>>>>>> Here is the parent entity (which has collection of child entities)
>>>>>>
>>>>>> package entities;
>>>>>>
>>>>>> import java.io.Serializable;
>>>>>> import javax.persistence.*;
>>>>>> import java.math.BigDecimal;
>>>>>> import java.util.Date;
>>>>>> import java.util.Set;
>>>>>>
>>>>>>
>>>>>> /**
>>>>>>  * The persistent class for the MARKET_DATA database table.
>>>>>>  *
>>>>>>  */
>>>>>> @Entity
>>>>>> @Table(name="MARKET_DATA")
>>>>>> public class MarketData implements Serializable {
>>>>>>         private static final long serialVersionUID = 1L;
>>>>>>         private long marketDataId;
>>>>>>         private String currencyCode;
>>>>>>         private Date dataDate;
>>>>>>         private BigDecimal lastPrice;
>>>>>>         private BigDecimal lastUpdatedPrice;
>>>>>>         private String name;
>>>>>>         private String requestId;
>>>>>>         private String requestIdType;
>>>>>>         private String subType;
>>>>>>         private String type;
>>>>>>         private String vendorId;
>>>>>>         private String vendorName;
>>>>>>         private Set
>>> <RiskFactor>
>>>  riskFactors;
>>>>>>
>>>>>>     public MarketData() {
>>>>>>     }
>>>>>>
>>>>>>
>>>>>>         @Id
>>>>>>         
>>>>>>@SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
>>>>>> sequenceName="MARKET_DATA_ID_SEQ")
>>>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>>>> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>>>>>>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false,
>>>>>>precision=19)
>>>>>>         public long getMarketDataId() {
>>>>>>                 return this.marketDataId;
>>>>>>         }
>>>>>>
>>>>>>         public void setMarketDataId(long marketDataId) {
>>>>>>                 this.marketDataId = marketDataId;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="CURRENCY_CODE", length=3)
>>>>>>         public String getCurrencyCode() {
>>>>>>                 return this.currencyCode;
>>>>>>         }
>>>>>>
>>>>>>         public void setCurrencyCode(String currencyCode) {
>>>>>>                 this.currencyCode = currencyCode;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>     @Temporal( TemporalType.DATE)
>>>>>>         @Column(name="DATA_DATE")
>>>>>>         public Date getDataDate() {
>>>>>>                 return this.dataDate;
>>>>>>         }
>>>>>>
>>>>>>         public void setDataDate(Date dataDate) {
>>>>>>                 this.dataDate = dataDate;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="LAST_PRICE", precision=20, scale=4)
>>>>>>         public BigDecimal getLastPrice() {
>>>>>>                 return this.lastPrice;
>>>>>>         }
>>>>>>
>>>>>>         public void setLastPrice(BigDecimal lastPrice) {
>>>>>>                 this.lastPrice = lastPrice;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>>>>>>         public BigDecimal getLastUpdatedPrice() {
>>>>>>                 return this.lastUpdatedPrice;
>>>>>>         }
>>>>>>
>>>>>>         public void setLastUpdatedPrice(BigDecimal
>>>>>>lastUpdatedPrice) {
>>>>>>                 this.lastUpdatedPrice = lastUpdatedPrice;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(length=100)
>>>>>>         public String getName() {
>>>>>>                 return this.name;
>>>>>>         }
>>>>>>
>>>>>>         public void setName(String name) {
>>>>>>                 this.name = name;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="REQUEST_ID", length=50)
>>>>>>         public String getRequestId() {
>>>>>>                 return this.requestId;
>>>>>>         }
>>>>>>
>>>>>>         public void setRequestId(String requestId) {
>>>>>>                 this.requestId = requestId;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="REQUEST_ID_TYPE", length=20)
>>>>>>         public String getRequestIdType() {
>>>>>>                 return this.requestIdType;
>>>>>>         }
>>>>>>
>>>>>>         public void setRequestIdType(String requestIdType) {
>>>>>>                 this.requestIdType = requestIdType;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="SUB_TYPE", length=100)
>>>>>>         public String getSubType() {
>>>>>>                 return this.subType;
>>>>>>         }
>>>>>>
>>>>>>         public void setSubType(String subType) {
>>>>>>                 this.subType = subType;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="\"TYPE\"", length=100)
>>>>>>         public String getType() {
>>>>>>                 return this.type;
>>>>>>         }
>>>>>>
>>>>>>         public void setType(String type) {
>>>>>>                 this.type = type;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="VENDOR_ID", length=50)
>>>>>>         public String getVendorId() {
>>>>>>                 return this.vendorId;
>>>>>>         }
>>>>>>
>>>>>>         public void setVendorId(String vendorId) {
>>>>>>                 this.vendorId = vendorId;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="VENDOR_NAME", length=100)
>>>>>>         public String getVendorName() {
>>>>>>                 return this.vendorName;
>>>>>>         }
>>>>>>
>>>>>>         public void setVendorName(String vendorName) {
>>>>>>                 this.vendorName = vendorName;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         //bi-directional many-to-many association to RiskFactor
>>>>>>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
>>>>>> CascadeType.REFRESH})
>>>>>>         @JoinTable(
>>>>>>                 name="MARKET_DATA_RISK_FACTOR"
>>>>>>                 , joinColumns={
>>>>>>                         @JoinColumn(name="MARKET_DATA_ID",
>>>>>>nullable=false)
>>>>>>                         }
>>>>>>                 , inverseJoinColumns={
>>>>>>                         @JoinColumn(name="RISK_FACTOR_ID",
>>>>>>nullable=false)
>>>>>>                         }
>>>>>>                 )
>>>>>>         public Set
>>> <RiskFactor>
>>>  getRiskFactors() {
>>>>>>                 return this.riskFactors;
>>>>>>         }
>>>>>>
>>>>>>         public void setRiskFactors(Set
>>> <RiskFactor>
>>>  riskFactors) {
>>>>>>                 this.riskFactors = riskFactors;
>>>>>>         }
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> package entities;
>>>>>>
>>>>>> import java.io.Serializable;
>>>>>> import javax.persistence.*;
>>>>>> import java.math.BigDecimal;
>>>>>> import java.util.Date;
>>>>>> import java.util.Set;
>>>>>>
>>>>>>
>>>>>> /**
>>>>>>  * The persistent class for the RISK_FACTOR database table.
>>>>>>  *
>>>>>>  */
>>>>>> @Entity
>>>>>> @Table(name="RISK_FACTOR")
>>>>>> public class RiskFactor implements Serializable {
>>>>>>         private static final long serialVersionUID = 1L;
>>>>>>         private long riskFactorId;
>>>>>>         private Date dataDate;
>>>>>>         private String name;
>>>>>>         private BigDecimal seq;
>>>>>>         private BigDecimal seq2;
>>>>>>         private String type;
>>>>>>         private BigDecimal value;
>>>>>>         private BigDecimal value2;
>>>>>>         private Set
>>> <MarketData>
>>>  marketData;
>>>>>>
>>>>>>     public RiskFactor() {
>>>>>>     }
>>>>>>
>>>>>>
>>>>>>         @Id
>>>>>>         
>>>>>>@SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
>>>>>> sequenceName="RISK_FACTOR_ID_SEQ")
>>>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>>>> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>>>>>>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false,
>>>>>>precision=19)
>>>>>>         public long getRiskFactorId() {
>>>>>>                 return this.riskFactorId;
>>>>>>         }
>>>>>>
>>>>>>         public void setRiskFactorId(long riskFactorId) {
>>>>>>                 this.riskFactorId = riskFactorId;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>     @Temporal( TemporalType.DATE)
>>>>>>         @Column(name="DATA_DATE")
>>>>>>         public Date getDataDate() {
>>>>>>                 return this.dataDate;
>>>>>>         }
>>>>>>
>>>>>>         public void setDataDate(Date dataDate) {
>>>>>>                 this.dataDate = dataDate;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(length=100)
>>>>>>         public String getName() {
>>>>>>                 return this.name;
>>>>>>         }
>>>>>>
>>>>>>         public void setName(String name) {
>>>>>>                 this.name = name;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(precision=1)
>>>>>>         public BigDecimal getSeq() {
>>>>>>                 return this.seq;
>>>>>>         }
>>>>>>
>>>>>>         public void setSeq(BigDecimal seq) {
>>>>>>                 this.seq = seq;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         public BigDecimal getSeq2() {
>>>>>>                 return this.seq2;
>>>>>>         }
>>>>>>
>>>>>>         public void setSeq2(BigDecimal seq2) {
>>>>>>                 this.seq2 = seq2;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="\"TYPE\"", length=100)
>>>>>>         public String getType() {
>>>>>>                 return this.type;
>>>>>>         }
>>>>>>
>>>>>>         public void setType(String type) {
>>>>>>                 this.type = type;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(name="\"VALUE\"", precision=20, scale=4)
>>>>>>         public BigDecimal getValue() {
>>>>>>                 return this.value;
>>>>>>         }
>>>>>>
>>>>>>         public void setValue(BigDecimal value) {
>>>>>>                 this.value = value;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         @Column(precision=20, scale=4)
>>>>>>         public BigDecimal getValue2() {
>>>>>>                 return this.value2;
>>>>>>         }
>>>>>>
>>>>>>         public void setValue2(BigDecimal value2) {
>>>>>>                 this.value2 = value2;
>>>>>>         }
>>>>>>
>>>>>>
>>>>>>         //bi-directional many-to-many association to MarketData
>>>>>>         @ManyToMany(mappedBy="riskFactors")
>>>>>>         public Set
>>> <MarketData>
>>>  getMarketData() {
>>>>>>                 return this.marketData;
>>>>>>         }
>>>>>>
>>>>>>         public void setMarketData(Set
>>> <MarketData>
>>>  marketData) {
>>>>>>                 this.marketData = marketData;
>>>>>>         }
>>>>>>
>>>>>> }
>>>>>> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
>>>>>> &lt;
>>
>>> christian.mueller@
>>
>>> &gt; wrote:
>>>>>>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which
>>>>>>>you
>>>>>>>are
>>>>>>> using. Can you upgrade?
>>>>>>>
>>>>>>> Best,
>>>>>>> Christian
>>>>>>>
>>>>>>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf &lt;
>>
>>> cwolf.algo@
>>
>>> &gt;
>>>>>>>wrote:
>>>>>>>
>>>>>>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>>>>>>> query.  If I have consumeDelete=false configured,
>>>>>>>> then it works and I see the entities.  When consumeDelete=false is
>>>>>>>> not
>>>>>>>> configured (default is to remove), then the error
>>>>>>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) -
>>>>>>>>but
>>>>>>>> "arg" is of type Object[] - not the entity.
>>>>>>>>
>>>>>>>> Second issue is I'd like the route to just perform the query once.
>>>>>>>> As it is, invokes the query in a loop.
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>>
>>>>>>>> Chris
>>>>>>>>
>>>>>>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>>>>>>> entities not being enhanced - I verified that with javap.
>>>>>>>>
>>>>>>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all
>>>>>>>>previous
>>>>
>>>>
>>
>>
>>
>>
>>
>> --
>> View this message in context:
>>http://camel.465427.n5.nabble.com/Re-JPA-component-throwing-Attempt-to-ca
>>st-instance-Ljava-lang-Object-PROBLEM-SOLVED-tp5725598p5725644.html
>> Sent from the Camel - Users mailing list archive at Nabble.com.



Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

Posted by Chris Wolf <cw...@gmail.com>.
Babak,

Thanks again for the reply.  I just wanted to mention that I think the
jpa component is
totally fine and usable as it is, and Camel, as a whole, is an awesome
framework.

However, I do have some remarks to make concerning the URI format for
jpa, you may
not agree, but I'd like to just make these remarks in closing on this issue.
(of course, feel free to reply, I'm just saying I don't you to feel
you have to.)

On Wed, Jan 16, 2013 at 8:53 AM, Babak Vahdat
<ba...@swissonline.ch> wrote:
> Yes I see your point but this is simply how the current codebase seems like,
> that's using
>
>   EntityManager.createNativeQuery(nativeQuery);
>
> is the *default* and if you want your entity object as the returned value
> then you have to *explicitly* ask for it. Changing this behaviour the way
> you ask for would break the existing applications relying on this behaviour.

 But in spite of what the documentation says:

    jpa:[entityClassName][?options]
    For consuming, the entityClassName is mandatory.

I find that "entityClassName" *can* be omitted in a jpa consumer and
you will get back
List<Object[]>, which is reasonable and expected.   However, if I
specify  "entityClassName"
I would expect the JpaComponent to return the results as a list of
those entities, which
it does not, but *could*, if the code were changed.

> IMHO it's also "clean" & "good" the way it is already is by the current
> camel-jpa codebase because if you look at the following three possible
> method signatures JPA EntityManager API provides for the native query:
>
>   Query createNativeQuery(java.lang.String sqlString)
>
>   Query createNativeQuery(java.lang.String sqlString, java.lang.Class
> resultClass)
>
>   Query createNativeQuery(java.lang.String sqlString, java.lang.String
> resultSetMapping)

This talk of the underlying EntityManager API is an implementation
detail - as a user
of the JPA component, I am only interested in the semantics of the URI
format and
options - I should not have to care about implementation details.

Having said that - if I specify an entity class in the URI, I would
expect the component
to do whatever needs to be done to populate the result set into such entities.
>
> Then it makes sense that Camel defaults to the first one having *one* single
> parameter, as given one parameter that's also what JPA itself defaults to as
> well, that is per default it returns you List<Object[]> in case you don't
> ask for anything extra!

Yes, but only if you don't specify entity class anywhere in the URI -
not in scheme-part,
not as "entityType" query option and not as "consumer.resultClass", on
in that case
should it return  List<Object[]>.

As I said, it's perfectly usable as-is - I only nit-pick because I was
initially confused.
Also if you have "entityType", I would expect the other option to be
consistently named,
i.e. "consumer.entityType", not "consumer.resultClass" -  or the other
way - around, but
I think "consumer.resultClass" is superfluous anyway since you should
only need to
specify the entity type *once* in the URI.

Anyway, you may not agree and that's fine, but at minimum, I would
make small changes to
the documentation:

1.) It says that for consumers the "entityTypeClassName" (immediately
following "jpa:")
     is mandatory, but I find that it is not - the endpoint still
queries the data.  I'm glad,
     because for a nativeQuery where List<Object[]> is expected, this
makes it more
     clear by not mentioning entity type anywhere in the URI.  For a
regular JPQL
     (consumer.query), it *will* return the results as entities, even without
     specifying the entity class *anywhere* in the URI.

     So I would remove the statement that says "entityTypeClassName is
mandatory" and
     and please, don't change the code to make it mandatory for the
case of List<Object[]>
     results.


2.) In the options table, the row where "consumer.resultClass" is
documented, in the remarks
    column, I would add to the note that mentions without this option,
the results are List<Object[]>
    - add to that: that in this case, consumeDelete=true will not work
and will cause a cast exception
    due to attempting to cast Object[] to PersistanceCapable.


Thanks for listening,

Chris

>
> BTW currently the third variant is not supported at all.
>
> Babak
>
>
> Chris Wolf wrote
>> On Tue, Jan 15, 2013 at 9:11 PM, Babak Vahdat
>> &lt;
>
>> babak.vahdat@
>
>> &gt; wrote:
>>>
>>>
>>> Am 16.01.13 01:07 schrieb "Chris Wolf" unter &lt;
>
>> cwolf.algo@
>
>> &gt;:
>>>
>>>>It was me not RTFM more carefully.  Sorry about that.  On the main
>>>>Camel-JPA page it mentions a query option
>>>>called "consumer.resultClass" which can be used to define the result
>>>>class for a native query.  So when I added that,
>>>>it all worked.
>>>>
>>>>Otherwise, without "consumer.resultClass", the native query returns
>>>>List&lt;Object[]&gt;.
>>>>
>>>>But here's the thing - if I'm already indicating the entity class in
>>>>the "scheme-specific-part" of the URI, (or entityType option)
>>>>then why must it be specified again?  Seems redundant and I think
>>>>seeing it there lulled me into thinking that the return
>>>>type was defined, even for a native query.
>>>
>>> It was my bad to not read through the thread before replying but happy to
>>> see you found the solution by yourself.
>>>
>>> Regarding your question why you should "repeat" yourself using the
>>> "consumer.resultClass" option, well without using that option the
>>> JpaConsumer makes use of:
>>>
>>>   EntityManager.createNativeQuery(nativeQuery);
>>>
>>> Which it's returned Query execution delivers List&lt;Object[]&gt; (See
>>> JPA 2
>>> spec. 3.8.6), however with that option being specified it makes use of:
>>>
>>>   EntityManager.createNativeQuery(nativeQuery, myEntityClass);
>>>
>>> API which then returns List
>> <myEntityClass>
>> . So the reason is the way how
>>> the native queries by the JPA API itself works.
>>
>> Right, but what I'm saying is that the JpaComponent already knows the
>> entity type from the "scheme-specific-part" of the URI,
>> i.e. "jpa:mypackage.myclass?bla,bla.."  - so why can't the
>> JpaComponent use that to invoke
>>  EntityManager.createNativeQuery(String, Class<?>)   ?
>>
>>
>>>
>>> Babak
>>>
>>>
>>>>
>>>>Thanks again,
>>>>
>>>>    -Chris
>>>>
>>>>On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf &lt;
>
>> cwolf.algo@
>
>> &gt; wrote:
>>>>> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>>>>>
>>>>>
>>>>>
>>>>> Here's the route, followed by console output, followed by entities
>>>>> code.  BTW, I notice that the data type of Body coming out
>>>>> of the jpa endpoint is of type Object[], I think this is part of the
>>>>> problem, because I put a breakpoint on line 159 in JpaConsumer,
>>>>> which is:
>>>>>
>>>>> getDeleteHandler().deleteObject(entityManager, result);
>>>>>
>>>>> ...and that  "result" is of type Object[] where each element is a
>>>>> field value of the entity cooresponding to the
>>>>> MarketData entity but it's NOT of type MarketData - hence the cast
>>>>> exception when EntityManager.remove() is called.
>>>>>
>>>>> Thanks Claus and Christian,
>>>>>
>>>>>     -Chris
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelete=tr
>>>>>ue&consumer.nativeQuery=select
>>>>> * from market_data where rownum < 10")
>>>>>
>>>>>.to("log:test.camel?showAll=true&multiline=true&level=INFO")
>>>>>                 .to("mock:foo");
>>>>>
>>>>> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>>> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
>>>>> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>>> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary class
>>>>> "org.apache.openjpa.jdbc.sql.OracleDictionary".
>>>>> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
>>>>> test.camel - Exchange[
>>>>> , Id:ID-cwolf-55710-1358279796309-0-2
>>>>> , ExchangePattern:InOnly
>>>>> ,
>>>>>Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=true&sh
>>>>>owAll=true,
>>>>> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
>>>>> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
>>>>> ,
>>>>>Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e99db4
>>>>>,
>>>>> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
>>>>> , BodyType:Object[]
>>>>> , Body:[Ljava.lang.Object;@a1e2da
>>>>> , Out: null
>>>>> ]
>>>>> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
>>>>> org.apache.camel.component.jpa.JpaConsumer - Error processing last
>>>>> message due:
>> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>>> Ensure that it has been enhanced.
>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
>>>>> successful processed message, and ignore this last failure.
>>>>> javax.persistence.PersistenceException:
>> <openjpa-2.2.1-r422266:1396819
>>>
>>>> nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
>>>>> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
>>>>> PersistenceCapable failed.  Ensure that it has been enhanced.
>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:102
>>>>>)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doInJpa
>>>>>(JpaTemplateTransactionStrategy.java:82)
>>>>>         at
>>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>>>>>         at
>>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInTrans
>>>>>action(JpaTemplateTransactionStrategy.java:80)
>>>>>         at
>>>>>org.springframework.transaction.support.TransactionTemplate.execute(Trans
>>>>>actionTemplate.java:130)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(Jpa
>>>>>TemplateTransactionStrategy.java:78)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>>>>>         at
>>>>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.j
>>>>>ava:139)
>>>>>         at
>>>>>org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.jav
>>>>>a:91)
>>>>>         at
>>>>>java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>>>>>         at
>>>>>java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317
>>>>>)
>>>>>         at
>>>>>java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>>>>>         at
>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.acce
>>>>>ss$101(ScheduledThreadPoolExecutor.java:98)
>>>>>         at
>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runP
>>>>>eriodic(ScheduledThreadPoolExecutor.java:180)
>>>>>         at
>>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(
>>>>>ScheduledThreadPoolExecutor.java:204)
>>>>>         at
>>>>>java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor
>>>>>.java:886)
>>>>>         at
>>>>>java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav
>>>>>a:908)
>>>>>         at java.lang.Thread.run(Thread.java:662)
>>>>> Caused by:
>> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>>> Ensure that it has been enhanced.
>>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>>         at
>>>>>org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.
>>>>>java:4667)
>>>>>         at
>>>>>org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java:268
>>>>>3)
>>>>>         at
>>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>>>>>         at
>>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>>>>>         at
>>>>>org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.java:1
>>>>>102)
>>>>>         at
>>>>>org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManagerImpl
>>>>>.java:730)
>>>>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>         at
>>>>>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java
>>>>>:39)
>>>>>         at
>>>>>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI
>>>>>mpl.java:25)
>>>>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>>>>         at
>>>>>org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHandler
>>>>>.invoke(JpaTemplate.java:425)
>>>>>         at $Proxy14.remove(Unknown Source)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer.jav
>>>>>a:337)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:
>>>>>159)
>>>>>         at
>>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:97)
>>>>>         ... 18 more
>>>>>
>>>>>
>>>>> Here is the parent entity (which has collection of child entities)
>>>>>
>>>>> package entities;
>>>>>
>>>>> import java.io.Serializable;
>>>>> import javax.persistence.*;
>>>>> import java.math.BigDecimal;
>>>>> import java.util.Date;
>>>>> import java.util.Set;
>>>>>
>>>>>
>>>>> /**
>>>>>  * The persistent class for the MARKET_DATA database table.
>>>>>  *
>>>>>  */
>>>>> @Entity
>>>>> @Table(name="MARKET_DATA")
>>>>> public class MarketData implements Serializable {
>>>>>         private static final long serialVersionUID = 1L;
>>>>>         private long marketDataId;
>>>>>         private String currencyCode;
>>>>>         private Date dataDate;
>>>>>         private BigDecimal lastPrice;
>>>>>         private BigDecimal lastUpdatedPrice;
>>>>>         private String name;
>>>>>         private String requestId;
>>>>>         private String requestIdType;
>>>>>         private String subType;
>>>>>         private String type;
>>>>>         private String vendorId;
>>>>>         private String vendorName;
>>>>>         private Set
>> <RiskFactor>
>>  riskFactors;
>>>>>
>>>>>     public MarketData() {
>>>>>     }
>>>>>
>>>>>
>>>>>         @Id
>>>>>         @SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
>>>>> sequenceName="MARKET_DATA_ID_SEQ")
>>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>>> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>>>>>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false,
>>>>>precision=19)
>>>>>         public long getMarketDataId() {
>>>>>                 return this.marketDataId;
>>>>>         }
>>>>>
>>>>>         public void setMarketDataId(long marketDataId) {
>>>>>                 this.marketDataId = marketDataId;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="CURRENCY_CODE", length=3)
>>>>>         public String getCurrencyCode() {
>>>>>                 return this.currencyCode;
>>>>>         }
>>>>>
>>>>>         public void setCurrencyCode(String currencyCode) {
>>>>>                 this.currencyCode = currencyCode;
>>>>>         }
>>>>>
>>>>>
>>>>>     @Temporal( TemporalType.DATE)
>>>>>         @Column(name="DATA_DATE")
>>>>>         public Date getDataDate() {
>>>>>                 return this.dataDate;
>>>>>         }
>>>>>
>>>>>         public void setDataDate(Date dataDate) {
>>>>>                 this.dataDate = dataDate;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="LAST_PRICE", precision=20, scale=4)
>>>>>         public BigDecimal getLastPrice() {
>>>>>                 return this.lastPrice;
>>>>>         }
>>>>>
>>>>>         public void setLastPrice(BigDecimal lastPrice) {
>>>>>                 this.lastPrice = lastPrice;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>>>>>         public BigDecimal getLastUpdatedPrice() {
>>>>>                 return this.lastUpdatedPrice;
>>>>>         }
>>>>>
>>>>>         public void setLastUpdatedPrice(BigDecimal lastUpdatedPrice) {
>>>>>                 this.lastUpdatedPrice = lastUpdatedPrice;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(length=100)
>>>>>         public String getName() {
>>>>>                 return this.name;
>>>>>         }
>>>>>
>>>>>         public void setName(String name) {
>>>>>                 this.name = name;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="REQUEST_ID", length=50)
>>>>>         public String getRequestId() {
>>>>>                 return this.requestId;
>>>>>         }
>>>>>
>>>>>         public void setRequestId(String requestId) {
>>>>>                 this.requestId = requestId;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="REQUEST_ID_TYPE", length=20)
>>>>>         public String getRequestIdType() {
>>>>>                 return this.requestIdType;
>>>>>         }
>>>>>
>>>>>         public void setRequestIdType(String requestIdType) {
>>>>>                 this.requestIdType = requestIdType;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="SUB_TYPE", length=100)
>>>>>         public String getSubType() {
>>>>>                 return this.subType;
>>>>>         }
>>>>>
>>>>>         public void setSubType(String subType) {
>>>>>                 this.subType = subType;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="\"TYPE\"", length=100)
>>>>>         public String getType() {
>>>>>                 return this.type;
>>>>>         }
>>>>>
>>>>>         public void setType(String type) {
>>>>>                 this.type = type;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="VENDOR_ID", length=50)
>>>>>         public String getVendorId() {
>>>>>                 return this.vendorId;
>>>>>         }
>>>>>
>>>>>         public void setVendorId(String vendorId) {
>>>>>                 this.vendorId = vendorId;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="VENDOR_NAME", length=100)
>>>>>         public String getVendorName() {
>>>>>                 return this.vendorName;
>>>>>         }
>>>>>
>>>>>         public void setVendorName(String vendorName) {
>>>>>                 this.vendorName = vendorName;
>>>>>         }
>>>>>
>>>>>
>>>>>         //bi-directional many-to-many association to RiskFactor
>>>>>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
>>>>> CascadeType.REFRESH})
>>>>>         @JoinTable(
>>>>>                 name="MARKET_DATA_RISK_FACTOR"
>>>>>                 , joinColumns={
>>>>>                         @JoinColumn(name="MARKET_DATA_ID",
>>>>>nullable=false)
>>>>>                         }
>>>>>                 , inverseJoinColumns={
>>>>>                         @JoinColumn(name="RISK_FACTOR_ID",
>>>>>nullable=false)
>>>>>                         }
>>>>>                 )
>>>>>         public Set
>> <RiskFactor>
>>  getRiskFactors() {
>>>>>                 return this.riskFactors;
>>>>>         }
>>>>>
>>>>>         public void setRiskFactors(Set
>> <RiskFactor>
>>  riskFactors) {
>>>>>                 this.riskFactors = riskFactors;
>>>>>         }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> package entities;
>>>>>
>>>>> import java.io.Serializable;
>>>>> import javax.persistence.*;
>>>>> import java.math.BigDecimal;
>>>>> import java.util.Date;
>>>>> import java.util.Set;
>>>>>
>>>>>
>>>>> /**
>>>>>  * The persistent class for the RISK_FACTOR database table.
>>>>>  *
>>>>>  */
>>>>> @Entity
>>>>> @Table(name="RISK_FACTOR")
>>>>> public class RiskFactor implements Serializable {
>>>>>         private static final long serialVersionUID = 1L;
>>>>>         private long riskFactorId;
>>>>>         private Date dataDate;
>>>>>         private String name;
>>>>>         private BigDecimal seq;
>>>>>         private BigDecimal seq2;
>>>>>         private String type;
>>>>>         private BigDecimal value;
>>>>>         private BigDecimal value2;
>>>>>         private Set
>> <MarketData>
>>  marketData;
>>>>>
>>>>>     public RiskFactor() {
>>>>>     }
>>>>>
>>>>>
>>>>>         @Id
>>>>>         @SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
>>>>> sequenceName="RISK_FACTOR_ID_SEQ")
>>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>>> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>>>>>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false,
>>>>>precision=19)
>>>>>         public long getRiskFactorId() {
>>>>>                 return this.riskFactorId;
>>>>>         }
>>>>>
>>>>>         public void setRiskFactorId(long riskFactorId) {
>>>>>                 this.riskFactorId = riskFactorId;
>>>>>         }
>>>>>
>>>>>
>>>>>     @Temporal( TemporalType.DATE)
>>>>>         @Column(name="DATA_DATE")
>>>>>         public Date getDataDate() {
>>>>>                 return this.dataDate;
>>>>>         }
>>>>>
>>>>>         public void setDataDate(Date dataDate) {
>>>>>                 this.dataDate = dataDate;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(length=100)
>>>>>         public String getName() {
>>>>>                 return this.name;
>>>>>         }
>>>>>
>>>>>         public void setName(String name) {
>>>>>                 this.name = name;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(precision=1)
>>>>>         public BigDecimal getSeq() {
>>>>>                 return this.seq;
>>>>>         }
>>>>>
>>>>>         public void setSeq(BigDecimal seq) {
>>>>>                 this.seq = seq;
>>>>>         }
>>>>>
>>>>>
>>>>>         public BigDecimal getSeq2() {
>>>>>                 return this.seq2;
>>>>>         }
>>>>>
>>>>>         public void setSeq2(BigDecimal seq2) {
>>>>>                 this.seq2 = seq2;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="\"TYPE\"", length=100)
>>>>>         public String getType() {
>>>>>                 return this.type;
>>>>>         }
>>>>>
>>>>>         public void setType(String type) {
>>>>>                 this.type = type;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(name="\"VALUE\"", precision=20, scale=4)
>>>>>         public BigDecimal getValue() {
>>>>>                 return this.value;
>>>>>         }
>>>>>
>>>>>         public void setValue(BigDecimal value) {
>>>>>                 this.value = value;
>>>>>         }
>>>>>
>>>>>
>>>>>         @Column(precision=20, scale=4)
>>>>>         public BigDecimal getValue2() {
>>>>>                 return this.value2;
>>>>>         }
>>>>>
>>>>>         public void setValue2(BigDecimal value2) {
>>>>>                 this.value2 = value2;
>>>>>         }
>>>>>
>>>>>
>>>>>         //bi-directional many-to-many association to MarketData
>>>>>         @ManyToMany(mappedBy="riskFactors")
>>>>>         public Set
>> <MarketData>
>>  getMarketData() {
>>>>>                 return this.marketData;
>>>>>         }
>>>>>
>>>>>         public void setMarketData(Set
>> <MarketData>
>>  marketData) {
>>>>>                 this.marketData = marketData;
>>>>>         }
>>>>>
>>>>> }
>>>>> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
>>>>> &lt;
>
>> christian.mueller@
>
>> &gt; wrote:
>>>>>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which you
>>>>>>are
>>>>>> using. Can you upgrade?
>>>>>>
>>>>>> Best,
>>>>>> Christian
>>>>>>
>>>>>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf &lt;
>
>> cwolf.algo@
>
>> &gt;
>>>>>>wrote:
>>>>>>
>>>>>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>>>>>> query.  If I have consumeDelete=false configured,
>>>>>>> then it works and I see the entities.  When consumeDelete=false is
>>>>>>> not
>>>>>>> configured (default is to remove), then the error
>>>>>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) - but
>>>>>>> "arg" is of type Object[] - not the entity.
>>>>>>>
>>>>>>> Second issue is I'd like the route to just perform the query once.
>>>>>>> As it is, invokes the query in a loop.
>>>>>>>
>>>>>>> Thanks
>>>>>>>
>>>>>>> Chris
>>>>>>>
>>>>>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>>>>>> entities not being enhanced - I verified that with javap.
>>>>>>>
>>>>>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all previous
>>>
>>>
>
>
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Re-JPA-component-throwing-Attempt-to-cast-instance-Ljava-lang-Object-PROBLEM-SOLVED-tp5725598p5725644.html
> Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

Posted by Babak Vahdat <ba...@swissonline.ch>.
Yes I see your point but this is simply how the current codebase seems like,
that's using

  EntityManager.createNativeQuery(nativeQuery);
  
is the *default* and if you want your entity object as the returned value
then you have to *explicitly* ask for it. Changing this behaviour the way
you ask for would break the existing applications relying on this behaviour.

IMHO it's also "clean" & "good" the way it is already is by the current
camel-jpa codebase because if you look at the following three possible
method signatures JPA EntityManager API provides for the native query:

  Query createNativeQuery(java.lang.String sqlString)

  Query createNativeQuery(java.lang.String sqlString, java.lang.Class
resultClass)

  Query createNativeQuery(java.lang.String sqlString, java.lang.String
resultSetMapping)
  
Then it makes sense that Camel defaults to the first one having *one* single
parameter, as given one parameter that's also what JPA itself defaults to as
well, that is per default it returns you List<Object[]> in case you don't
ask for anything extra!

BTW currently the third variant is not supported at all.

Babak


Chris Wolf wrote
> On Tue, Jan 15, 2013 at 9:11 PM, Babak Vahdat
> &lt;

> babak.vahdat@

> &gt; wrote:
>>
>>
>> Am 16.01.13 01:07 schrieb "Chris Wolf" unter &lt;

> cwolf.algo@

> &gt;:
>>
>>>It was me not RTFM more carefully.  Sorry about that.  On the main
>>>Camel-JPA page it mentions a query option
>>>called "consumer.resultClass" which can be used to define the result
>>>class for a native query.  So when I added that,
>>>it all worked.
>>>
>>>Otherwise, without "consumer.resultClass", the native query returns
>>>List&lt;Object[]&gt;.
>>>
>>>But here's the thing - if I'm already indicating the entity class in
>>>the "scheme-specific-part" of the URI, (or entityType option)
>>>then why must it be specified again?  Seems redundant and I think
>>>seeing it there lulled me into thinking that the return
>>>type was defined, even for a native query.
>>
>> It was my bad to not read through the thread before replying but happy to
>> see you found the solution by yourself.
>>
>> Regarding your question why you should "repeat" yourself using the
>> "consumer.resultClass" option, well without using that option the
>> JpaConsumer makes use of:
>>
>>   EntityManager.createNativeQuery(nativeQuery);
>>
>> Which it's returned Query execution delivers List&lt;Object[]&gt; (See
>> JPA 2
>> spec. 3.8.6), however with that option being specified it makes use of:
>>
>>   EntityManager.createNativeQuery(nativeQuery, myEntityClass);
>>
>> API which then returns List
> <myEntityClass>
> . So the reason is the way how
>> the native queries by the JPA API itself works.
> 
> Right, but what I'm saying is that the JpaComponent already knows the
> entity type from the "scheme-specific-part" of the URI,
> i.e. "jpa:mypackage.myclass?bla,bla.."  - so why can't the
> JpaComponent use that to invoke
>  EntityManager.createNativeQuery(String, Class<?>)   ?
> 
> 
>>
>> Babak
>>
>>
>>>
>>>Thanks again,
>>>
>>>    -Chris
>>>
>>>On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf &lt;

> cwolf.algo@

> &gt; wrote:
>>>> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>>>>
>>>>
>>>>
>>>> Here's the route, followed by console output, followed by entities
>>>> code.  BTW, I notice that the data type of Body coming out
>>>> of the jpa endpoint is of type Object[], I think this is part of the
>>>> problem, because I put a breakpoint on line 159 in JpaConsumer,
>>>> which is:
>>>>
>>>> getDeleteHandler().deleteObject(entityManager, result);
>>>>
>>>> ...and that  "result" is of type Object[] where each element is a
>>>> field value of the entity cooresponding to the
>>>> MarketData entity but it's NOT of type MarketData - hence the cast
>>>> exception when EntityManager.remove() is called.
>>>>
>>>> Thanks Claus and Christian,
>>>>
>>>>     -Chris
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelete=tr
>>>>ue&consumer.nativeQuery=select
>>>> * from market_data where rownum < 10")
>>>>
>>>>.to("log:test.camel?showAll=true&multiline=true&level=INFO")
>>>>                 .to("mock:foo");
>>>>
>>>> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
>>>> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
>>>> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary class
>>>> "org.apache.openjpa.jdbc.sql.OracleDictionary".
>>>> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
>>>> test.camel - Exchange[
>>>> , Id:ID-cwolf-55710-1358279796309-0-2
>>>> , ExchangePattern:InOnly
>>>> ,
>>>>Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=true&sh
>>>>owAll=true,
>>>> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
>>>> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
>>>> ,
>>>>Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e99db4
>>>>,
>>>> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
>>>> , BodyType:Object[]
>>>> , Body:[Ljava.lang.Object;@a1e2da
>>>> , Out: null
>>>> ]
>>>> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
>>>> org.apache.camel.component.jpa.JpaConsumer - Error processing last
>>>> message due: 
> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>> Ensure that it has been enhanced.
>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
>>>> successful processed message, and ignore this last failure.
>>>> javax.persistence.PersistenceException: 
> <openjpa-2.2.1-r422266:1396819
>>
>>> nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
>>>> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
>>>> PersistenceCapable failed.  Ensure that it has been enhanced.
>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>         at
>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:102
>>>>)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doInJpa
>>>>(JpaTemplateTransactionStrategy.java:82)
>>>>         at
>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>>>>         at
>>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInTrans
>>>>action(JpaTemplateTransactionStrategy.java:80)
>>>>         at
>>>>org.springframework.transaction.support.TransactionTemplate.execute(Trans
>>>>actionTemplate.java:130)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(Jpa
>>>>TemplateTransactionStrategy.java:78)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>>>>         at
>>>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.j
>>>>ava:139)
>>>>         at
>>>>org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.jav
>>>>a:91)
>>>>         at
>>>>java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>>>>         at
>>>>java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317
>>>>)
>>>>         at
>>>>java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>>>>         at
>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.acce
>>>>ss$101(ScheduledThreadPoolExecutor.java:98)
>>>>         at
>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runP
>>>>eriodic(ScheduledThreadPoolExecutor.java:180)
>>>>         at
>>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(
>>>>ScheduledThreadPoolExecutor.java:204)
>>>>         at
>>>>java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor
>>>>.java:886)
>>>>         at
>>>>java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav
>>>>a:908)
>>>>         at java.lang.Thread.run(Thread.java:662)
>>>> Caused by: 
> <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>>> Ensure that it has been enhanced.
>>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>>         at
>>>>org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.
>>>>java:4667)
>>>>         at
>>>>org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java:268
>>>>3)
>>>>         at
>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>>>>         at
>>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>>>>         at
>>>>org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.java:1
>>>>102)
>>>>         at
>>>>org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManagerImpl
>>>>.java:730)
>>>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>         at
>>>>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java
>>>>:39)
>>>>         at
>>>>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI
>>>>mpl.java:25)
>>>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>>>         at
>>>>org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHandler
>>>>.invoke(JpaTemplate.java:425)
>>>>         at $Proxy14.remove(Unknown Source)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer.jav
>>>>a:337)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:
>>>>159)
>>>>         at
>>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:97)
>>>>         ... 18 more
>>>>
>>>>
>>>> Here is the parent entity (which has collection of child entities)
>>>>
>>>> package entities;
>>>>
>>>> import java.io.Serializable;
>>>> import javax.persistence.*;
>>>> import java.math.BigDecimal;
>>>> import java.util.Date;
>>>> import java.util.Set;
>>>>
>>>>
>>>> /**
>>>>  * The persistent class for the MARKET_DATA database table.
>>>>  *
>>>>  */
>>>> @Entity
>>>> @Table(name="MARKET_DATA")
>>>> public class MarketData implements Serializable {
>>>>         private static final long serialVersionUID = 1L;
>>>>         private long marketDataId;
>>>>         private String currencyCode;
>>>>         private Date dataDate;
>>>>         private BigDecimal lastPrice;
>>>>         private BigDecimal lastUpdatedPrice;
>>>>         private String name;
>>>>         private String requestId;
>>>>         private String requestIdType;
>>>>         private String subType;
>>>>         private String type;
>>>>         private String vendorId;
>>>>         private String vendorName;
>>>>         private Set
> <RiskFactor>
>  riskFactors;
>>>>
>>>>     public MarketData() {
>>>>     }
>>>>
>>>>
>>>>         @Id
>>>>         @SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
>>>> sequenceName="MARKET_DATA_ID_SEQ")
>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>>>>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false,
>>>>precision=19)
>>>>         public long getMarketDataId() {
>>>>                 return this.marketDataId;
>>>>         }
>>>>
>>>>         public void setMarketDataId(long marketDataId) {
>>>>                 this.marketDataId = marketDataId;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="CURRENCY_CODE", length=3)
>>>>         public String getCurrencyCode() {
>>>>                 return this.currencyCode;
>>>>         }
>>>>
>>>>         public void setCurrencyCode(String currencyCode) {
>>>>                 this.currencyCode = currencyCode;
>>>>         }
>>>>
>>>>
>>>>     @Temporal( TemporalType.DATE)
>>>>         @Column(name="DATA_DATE")
>>>>         public Date getDataDate() {
>>>>                 return this.dataDate;
>>>>         }
>>>>
>>>>         public void setDataDate(Date dataDate) {
>>>>                 this.dataDate = dataDate;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="LAST_PRICE", precision=20, scale=4)
>>>>         public BigDecimal getLastPrice() {
>>>>                 return this.lastPrice;
>>>>         }
>>>>
>>>>         public void setLastPrice(BigDecimal lastPrice) {
>>>>                 this.lastPrice = lastPrice;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>>>>         public BigDecimal getLastUpdatedPrice() {
>>>>                 return this.lastUpdatedPrice;
>>>>         }
>>>>
>>>>         public void setLastUpdatedPrice(BigDecimal lastUpdatedPrice) {
>>>>                 this.lastUpdatedPrice = lastUpdatedPrice;
>>>>         }
>>>>
>>>>
>>>>         @Column(length=100)
>>>>         public String getName() {
>>>>                 return this.name;
>>>>         }
>>>>
>>>>         public void setName(String name) {
>>>>                 this.name = name;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="REQUEST_ID", length=50)
>>>>         public String getRequestId() {
>>>>                 return this.requestId;
>>>>         }
>>>>
>>>>         public void setRequestId(String requestId) {
>>>>                 this.requestId = requestId;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="REQUEST_ID_TYPE", length=20)
>>>>         public String getRequestIdType() {
>>>>                 return this.requestIdType;
>>>>         }
>>>>
>>>>         public void setRequestIdType(String requestIdType) {
>>>>                 this.requestIdType = requestIdType;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="SUB_TYPE", length=100)
>>>>         public String getSubType() {
>>>>                 return this.subType;
>>>>         }
>>>>
>>>>         public void setSubType(String subType) {
>>>>                 this.subType = subType;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="\"TYPE\"", length=100)
>>>>         public String getType() {
>>>>                 return this.type;
>>>>         }
>>>>
>>>>         public void setType(String type) {
>>>>                 this.type = type;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="VENDOR_ID", length=50)
>>>>         public String getVendorId() {
>>>>                 return this.vendorId;
>>>>         }
>>>>
>>>>         public void setVendorId(String vendorId) {
>>>>                 this.vendorId = vendorId;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="VENDOR_NAME", length=100)
>>>>         public String getVendorName() {
>>>>                 return this.vendorName;
>>>>         }
>>>>
>>>>         public void setVendorName(String vendorName) {
>>>>                 this.vendorName = vendorName;
>>>>         }
>>>>
>>>>
>>>>         //bi-directional many-to-many association to RiskFactor
>>>>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
>>>> CascadeType.REFRESH})
>>>>         @JoinTable(
>>>>                 name="MARKET_DATA_RISK_FACTOR"
>>>>                 , joinColumns={
>>>>                         @JoinColumn(name="MARKET_DATA_ID",
>>>>nullable=false)
>>>>                         }
>>>>                 , inverseJoinColumns={
>>>>                         @JoinColumn(name="RISK_FACTOR_ID",
>>>>nullable=false)
>>>>                         }
>>>>                 )
>>>>         public Set
> <RiskFactor>
>  getRiskFactors() {
>>>>                 return this.riskFactors;
>>>>         }
>>>>
>>>>         public void setRiskFactors(Set
> <RiskFactor>
>  riskFactors) {
>>>>                 this.riskFactors = riskFactors;
>>>>         }
>>>> }
>>>>
>>>>
>>>>
>>>> package entities;
>>>>
>>>> import java.io.Serializable;
>>>> import javax.persistence.*;
>>>> import java.math.BigDecimal;
>>>> import java.util.Date;
>>>> import java.util.Set;
>>>>
>>>>
>>>> /**
>>>>  * The persistent class for the RISK_FACTOR database table.
>>>>  *
>>>>  */
>>>> @Entity
>>>> @Table(name="RISK_FACTOR")
>>>> public class RiskFactor implements Serializable {
>>>>         private static final long serialVersionUID = 1L;
>>>>         private long riskFactorId;
>>>>         private Date dataDate;
>>>>         private String name;
>>>>         private BigDecimal seq;
>>>>         private BigDecimal seq2;
>>>>         private String type;
>>>>         private BigDecimal value;
>>>>         private BigDecimal value2;
>>>>         private Set
> <MarketData>
>  marketData;
>>>>
>>>>     public RiskFactor() {
>>>>     }
>>>>
>>>>
>>>>         @Id
>>>>         @SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
>>>> sequenceName="RISK_FACTOR_ID_SEQ")
>>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>>> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>>>>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false,
>>>>precision=19)
>>>>         public long getRiskFactorId() {
>>>>                 return this.riskFactorId;
>>>>         }
>>>>
>>>>         public void setRiskFactorId(long riskFactorId) {
>>>>                 this.riskFactorId = riskFactorId;
>>>>         }
>>>>
>>>>
>>>>     @Temporal( TemporalType.DATE)
>>>>         @Column(name="DATA_DATE")
>>>>         public Date getDataDate() {
>>>>                 return this.dataDate;
>>>>         }
>>>>
>>>>         public void setDataDate(Date dataDate) {
>>>>                 this.dataDate = dataDate;
>>>>         }
>>>>
>>>>
>>>>         @Column(length=100)
>>>>         public String getName() {
>>>>                 return this.name;
>>>>         }
>>>>
>>>>         public void setName(String name) {
>>>>                 this.name = name;
>>>>         }
>>>>
>>>>
>>>>         @Column(precision=1)
>>>>         public BigDecimal getSeq() {
>>>>                 return this.seq;
>>>>         }
>>>>
>>>>         public void setSeq(BigDecimal seq) {
>>>>                 this.seq = seq;
>>>>         }
>>>>
>>>>
>>>>         public BigDecimal getSeq2() {
>>>>                 return this.seq2;
>>>>         }
>>>>
>>>>         public void setSeq2(BigDecimal seq2) {
>>>>                 this.seq2 = seq2;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="\"TYPE\"", length=100)
>>>>         public String getType() {
>>>>                 return this.type;
>>>>         }
>>>>
>>>>         public void setType(String type) {
>>>>                 this.type = type;
>>>>         }
>>>>
>>>>
>>>>         @Column(name="\"VALUE\"", precision=20, scale=4)
>>>>         public BigDecimal getValue() {
>>>>                 return this.value;
>>>>         }
>>>>
>>>>         public void setValue(BigDecimal value) {
>>>>                 this.value = value;
>>>>         }
>>>>
>>>>
>>>>         @Column(precision=20, scale=4)
>>>>         public BigDecimal getValue2() {
>>>>                 return this.value2;
>>>>         }
>>>>
>>>>         public void setValue2(BigDecimal value2) {
>>>>                 this.value2 = value2;
>>>>         }
>>>>
>>>>
>>>>         //bi-directional many-to-many association to MarketData
>>>>         @ManyToMany(mappedBy="riskFactors")
>>>>         public Set
> <MarketData>
>  getMarketData() {
>>>>                 return this.marketData;
>>>>         }
>>>>
>>>>         public void setMarketData(Set
> <MarketData>
>  marketData) {
>>>>                 this.marketData = marketData;
>>>>         }
>>>>
>>>> }
>>>> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
>>>> &lt;

> christian.mueller@

> &gt; wrote:
>>>>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which you
>>>>>are
>>>>> using. Can you upgrade?
>>>>>
>>>>> Best,
>>>>> Christian
>>>>>
>>>>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf &lt;

> cwolf.algo@

> &gt;
>>>>>wrote:
>>>>>
>>>>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>>>>> query.  If I have consumeDelete=false configured,
>>>>>> then it works and I see the entities.  When consumeDelete=false is
>>>>>> not
>>>>>> configured (default is to remove), then the error
>>>>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) - but
>>>>>> "arg" is of type Object[] - not the entity.
>>>>>>
>>>>>> Second issue is I'd like the route to just perform the query once.
>>>>>> As it is, invokes the query in a loop.
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> Chris
>>>>>>
>>>>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>>>>> entities not being enhanced - I verified that with javap.
>>>>>>
>>>>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all previous
>>
>>





--
View this message in context: http://camel.465427.n5.nabble.com/Re-JPA-component-throwing-Attempt-to-cast-instance-Ljava-lang-Object-PROBLEM-SOLVED-tp5725598p5725644.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

Posted by Chris Wolf <cw...@gmail.com>.
On Tue, Jan 15, 2013 at 9:11 PM, Babak Vahdat
<ba...@swissonline.ch> wrote:
>
>
> Am 16.01.13 01:07 schrieb "Chris Wolf" unter <cw...@gmail.com>:
>
>>It was me not RTFM more carefully.  Sorry about that.  On the main
>>Camel-JPA page it mentions a query option
>>called "consumer.resultClass" which can be used to define the result
>>class for a native query.  So when I added that,
>>it all worked.
>>
>>Otherwise, without "consumer.resultClass", the native query returns
>>List<Object[]>.
>>
>>But here's the thing - if I'm already indicating the entity class in
>>the "scheme-specific-part" of the URI, (or entityType option)
>>then why must it be specified again?  Seems redundant and I think
>>seeing it there lulled me into thinking that the return
>>type was defined, even for a native query.
>
> It was my bad to not read through the thread before replying but happy to
> see you found the solution by yourself.
>
> Regarding your question why you should "repeat" yourself using the
> "consumer.resultClass" option, well without using that option the
> JpaConsumer makes use of:
>
>   EntityManager.createNativeQuery(nativeQuery);
>
> Which it's returned Query execution delivers List<Object[]> (See JPA 2
> spec. 3.8.6), however with that option being specified it makes use of:
>
>   EntityManager.createNativeQuery(nativeQuery, myEntityClass);
>
> API which then returns List<myEntityClass>. So the reason is the way how
> the native queries by the JPA API itself works.

Right, but what I'm saying is that the JpaComponent already knows the
entity type from the "scheme-specific-part" of the URI,
i.e. "jpa:mypackage.myclass?bla,bla.."  - so why can't the
JpaComponent use that to invoke
 EntityManager.createNativeQuery(String, Class<?>)   ?


>
> Babak
>
>
>>
>>Thanks again,
>>
>>    -Chris
>>
>>On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf <cw...@gmail.com> wrote:
>>> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>>>
>>>
>>>
>>> Here's the route, followed by console output, followed by entities
>>> code.  BTW, I notice that the data type of Body coming out
>>> of the jpa endpoint is of type Object[], I think this is part of the
>>> problem, because I put a breakpoint on line 159 in JpaConsumer,
>>> which is:
>>>
>>> getDeleteHandler().deleteObject(entityManager, result);
>>>
>>> ...and that  "result" is of type Object[] where each element is a
>>> field value of the entity cooresponding to the
>>> MarketData entity but it's NOT of type MarketData - hence the cast
>>> exception when EntityManager.remove() is called.
>>>
>>> Thanks Claus and Christian,
>>>
>>>     -Chris
>>>
>>>
>>>
>>>
>>>
>>>
>>>from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelete=tr
>>>ue&consumer.nativeQuery=select
>>> * from market_data where rownum < 10")
>>>
>>>.to("log:test.camel?showAll=true&multiline=true&level=INFO")
>>>                 .to("mock:foo");
>>>
>>> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
>>> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
>>> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
>>> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary class
>>> "org.apache.openjpa.jdbc.sql.OracleDictionary".
>>> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
>>> test.camel - Exchange[
>>> , Id:ID-cwolf-55710-1358279796309-0-2
>>> , ExchangePattern:InOnly
>>> ,
>>>Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=true&sh
>>>owAll=true,
>>> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
>>> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
>>> ,
>>>Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e99db4
>>>,
>>> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
>>> , BodyType:Object[]
>>> , Body:[Ljava.lang.Object;@a1e2da
>>> , Out: null
>>> ]
>>> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
>>> org.apache.camel.component.jpa.JpaConsumer - Error processing last
>>> message due: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>> Ensure that it has been enhanced.
>>> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
>>> successful processed message, and ignore this last failure.
>>> javax.persistence.PersistenceException: <openjpa-2.2.1-r422266:1396819
>>> nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
>>> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
>>> PersistenceCapable failed.  Ensure that it has been enhanced.
>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>         at
>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:102
>>>)
>>>         at
>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doInJpa
>>>(JpaTemplateTransactionStrategy.java:82)
>>>         at
>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>>>         at
>>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>>>         at
>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInTrans
>>>action(JpaTemplateTransactionStrategy.java:80)
>>>         at
>>>org.springframework.transaction.support.TransactionTemplate.execute(Trans
>>>actionTemplate.java:130)
>>>         at
>>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(Jpa
>>>TemplateTransactionStrategy.java:78)
>>>         at
>>>org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>>>         at
>>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.j
>>>ava:139)
>>>         at
>>>org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.jav
>>>a:91)
>>>         at
>>>java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>>>         at
>>>java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317
>>>)
>>>         at
>>>java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>>>         at
>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.acce
>>>ss$101(ScheduledThreadPoolExecutor.java:98)
>>>         at
>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runP
>>>eriodic(ScheduledThreadPoolExecutor.java:180)
>>>         at
>>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(
>>>ScheduledThreadPoolExecutor.java:204)
>>>         at
>>>java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor
>>>.java:886)
>>>         at
>>>java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav
>>>a:908)
>>>         at java.lang.Thread.run(Thread.java:662)
>>> Caused by: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>>> Ensure that it has been enhanced.
>>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>>         at
>>>org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.
>>>java:4667)
>>>         at
>>>org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java:268
>>>3)
>>>         at
>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>>>         at
>>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>>>         at
>>>org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.java:1
>>>102)
>>>         at
>>>org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManagerImpl
>>>.java:730)
>>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>         at
>>>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java
>>>:39)
>>>         at
>>>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI
>>>mpl.java:25)
>>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>>         at
>>>org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHandler
>>>.invoke(JpaTemplate.java:425)
>>>         at $Proxy14.remove(Unknown Source)
>>>         at
>>>org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer.jav
>>>a:337)
>>>         at
>>>org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:
>>>159)
>>>         at
>>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:97)
>>>         ... 18 more
>>>
>>>
>>> Here is the parent entity (which has collection of child entities)
>>>
>>> package entities;
>>>
>>> import java.io.Serializable;
>>> import javax.persistence.*;
>>> import java.math.BigDecimal;
>>> import java.util.Date;
>>> import java.util.Set;
>>>
>>>
>>> /**
>>>  * The persistent class for the MARKET_DATA database table.
>>>  *
>>>  */
>>> @Entity
>>> @Table(name="MARKET_DATA")
>>> public class MarketData implements Serializable {
>>>         private static final long serialVersionUID = 1L;
>>>         private long marketDataId;
>>>         private String currencyCode;
>>>         private Date dataDate;
>>>         private BigDecimal lastPrice;
>>>         private BigDecimal lastUpdatedPrice;
>>>         private String name;
>>>         private String requestId;
>>>         private String requestIdType;
>>>         private String subType;
>>>         private String type;
>>>         private String vendorId;
>>>         private String vendorName;
>>>         private Set<RiskFactor> riskFactors;
>>>
>>>     public MarketData() {
>>>     }
>>>
>>>
>>>         @Id
>>>         @SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
>>> sequenceName="MARKET_DATA_ID_SEQ")
>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>>>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false,
>>>precision=19)
>>>         public long getMarketDataId() {
>>>                 return this.marketDataId;
>>>         }
>>>
>>>         public void setMarketDataId(long marketDataId) {
>>>                 this.marketDataId = marketDataId;
>>>         }
>>>
>>>
>>>         @Column(name="CURRENCY_CODE", length=3)
>>>         public String getCurrencyCode() {
>>>                 return this.currencyCode;
>>>         }
>>>
>>>         public void setCurrencyCode(String currencyCode) {
>>>                 this.currencyCode = currencyCode;
>>>         }
>>>
>>>
>>>     @Temporal( TemporalType.DATE)
>>>         @Column(name="DATA_DATE")
>>>         public Date getDataDate() {
>>>                 return this.dataDate;
>>>         }
>>>
>>>         public void setDataDate(Date dataDate) {
>>>                 this.dataDate = dataDate;
>>>         }
>>>
>>>
>>>         @Column(name="LAST_PRICE", precision=20, scale=4)
>>>         public BigDecimal getLastPrice() {
>>>                 return this.lastPrice;
>>>         }
>>>
>>>         public void setLastPrice(BigDecimal lastPrice) {
>>>                 this.lastPrice = lastPrice;
>>>         }
>>>
>>>
>>>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>>>         public BigDecimal getLastUpdatedPrice() {
>>>                 return this.lastUpdatedPrice;
>>>         }
>>>
>>>         public void setLastUpdatedPrice(BigDecimal lastUpdatedPrice) {
>>>                 this.lastUpdatedPrice = lastUpdatedPrice;
>>>         }
>>>
>>>
>>>         @Column(length=100)
>>>         public String getName() {
>>>                 return this.name;
>>>         }
>>>
>>>         public void setName(String name) {
>>>                 this.name = name;
>>>         }
>>>
>>>
>>>         @Column(name="REQUEST_ID", length=50)
>>>         public String getRequestId() {
>>>                 return this.requestId;
>>>         }
>>>
>>>         public void setRequestId(String requestId) {
>>>                 this.requestId = requestId;
>>>         }
>>>
>>>
>>>         @Column(name="REQUEST_ID_TYPE", length=20)
>>>         public String getRequestIdType() {
>>>                 return this.requestIdType;
>>>         }
>>>
>>>         public void setRequestIdType(String requestIdType) {
>>>                 this.requestIdType = requestIdType;
>>>         }
>>>
>>>
>>>         @Column(name="SUB_TYPE", length=100)
>>>         public String getSubType() {
>>>                 return this.subType;
>>>         }
>>>
>>>         public void setSubType(String subType) {
>>>                 this.subType = subType;
>>>         }
>>>
>>>
>>>         @Column(name="\"TYPE\"", length=100)
>>>         public String getType() {
>>>                 return this.type;
>>>         }
>>>
>>>         public void setType(String type) {
>>>                 this.type = type;
>>>         }
>>>
>>>
>>>         @Column(name="VENDOR_ID", length=50)
>>>         public String getVendorId() {
>>>                 return this.vendorId;
>>>         }
>>>
>>>         public void setVendorId(String vendorId) {
>>>                 this.vendorId = vendorId;
>>>         }
>>>
>>>
>>>         @Column(name="VENDOR_NAME", length=100)
>>>         public String getVendorName() {
>>>                 return this.vendorName;
>>>         }
>>>
>>>         public void setVendorName(String vendorName) {
>>>                 this.vendorName = vendorName;
>>>         }
>>>
>>>
>>>         //bi-directional many-to-many association to RiskFactor
>>>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
>>> CascadeType.REFRESH})
>>>         @JoinTable(
>>>                 name="MARKET_DATA_RISK_FACTOR"
>>>                 , joinColumns={
>>>                         @JoinColumn(name="MARKET_DATA_ID",
>>>nullable=false)
>>>                         }
>>>                 , inverseJoinColumns={
>>>                         @JoinColumn(name="RISK_FACTOR_ID",
>>>nullable=false)
>>>                         }
>>>                 )
>>>         public Set<RiskFactor> getRiskFactors() {
>>>                 return this.riskFactors;
>>>         }
>>>
>>>         public void setRiskFactors(Set<RiskFactor> riskFactors) {
>>>                 this.riskFactors = riskFactors;
>>>         }
>>> }
>>>
>>>
>>>
>>> package entities;
>>>
>>> import java.io.Serializable;
>>> import javax.persistence.*;
>>> import java.math.BigDecimal;
>>> import java.util.Date;
>>> import java.util.Set;
>>>
>>>
>>> /**
>>>  * The persistent class for the RISK_FACTOR database table.
>>>  *
>>>  */
>>> @Entity
>>> @Table(name="RISK_FACTOR")
>>> public class RiskFactor implements Serializable {
>>>         private static final long serialVersionUID = 1L;
>>>         private long riskFactorId;
>>>         private Date dataDate;
>>>         private String name;
>>>         private BigDecimal seq;
>>>         private BigDecimal seq2;
>>>         private String type;
>>>         private BigDecimal value;
>>>         private BigDecimal value2;
>>>         private Set<MarketData> marketData;
>>>
>>>     public RiskFactor() {
>>>     }
>>>
>>>
>>>         @Id
>>>         @SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
>>> sequenceName="RISK_FACTOR_ID_SEQ")
>>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>>> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>>>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false,
>>>precision=19)
>>>         public long getRiskFactorId() {
>>>                 return this.riskFactorId;
>>>         }
>>>
>>>         public void setRiskFactorId(long riskFactorId) {
>>>                 this.riskFactorId = riskFactorId;
>>>         }
>>>
>>>
>>>     @Temporal( TemporalType.DATE)
>>>         @Column(name="DATA_DATE")
>>>         public Date getDataDate() {
>>>                 return this.dataDate;
>>>         }
>>>
>>>         public void setDataDate(Date dataDate) {
>>>                 this.dataDate = dataDate;
>>>         }
>>>
>>>
>>>         @Column(length=100)
>>>         public String getName() {
>>>                 return this.name;
>>>         }
>>>
>>>         public void setName(String name) {
>>>                 this.name = name;
>>>         }
>>>
>>>
>>>         @Column(precision=1)
>>>         public BigDecimal getSeq() {
>>>                 return this.seq;
>>>         }
>>>
>>>         public void setSeq(BigDecimal seq) {
>>>                 this.seq = seq;
>>>         }
>>>
>>>
>>>         public BigDecimal getSeq2() {
>>>                 return this.seq2;
>>>         }
>>>
>>>         public void setSeq2(BigDecimal seq2) {
>>>                 this.seq2 = seq2;
>>>         }
>>>
>>>
>>>         @Column(name="\"TYPE\"", length=100)
>>>         public String getType() {
>>>                 return this.type;
>>>         }
>>>
>>>         public void setType(String type) {
>>>                 this.type = type;
>>>         }
>>>
>>>
>>>         @Column(name="\"VALUE\"", precision=20, scale=4)
>>>         public BigDecimal getValue() {
>>>                 return this.value;
>>>         }
>>>
>>>         public void setValue(BigDecimal value) {
>>>                 this.value = value;
>>>         }
>>>
>>>
>>>         @Column(precision=20, scale=4)
>>>         public BigDecimal getValue2() {
>>>                 return this.value2;
>>>         }
>>>
>>>         public void setValue2(BigDecimal value2) {
>>>                 this.value2 = value2;
>>>         }
>>>
>>>
>>>         //bi-directional many-to-many association to MarketData
>>>         @ManyToMany(mappedBy="riskFactors")
>>>         public Set<MarketData> getMarketData() {
>>>                 return this.marketData;
>>>         }
>>>
>>>         public void setMarketData(Set<MarketData> marketData) {
>>>                 this.marketData = marketData;
>>>         }
>>>
>>> }
>>> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
>>> <ch...@gmail.com> wrote:
>>>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which you
>>>>are
>>>> using. Can you upgrade?
>>>>
>>>> Best,
>>>> Christian
>>>>
>>>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf <cw...@gmail.com>
>>>>wrote:
>>>>
>>>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>>>> query.  If I have consumeDelete=false configured,
>>>>> then it works and I see the entities.  When consumeDelete=false is not
>>>>> configured (default is to remove), then the error
>>>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) - but
>>>>> "arg" is of type Object[] - not the entity.
>>>>>
>>>>> Second issue is I'd like the route to just perform the query once.
>>>>> As it is, invokes the query in a loop.
>>>>>
>>>>> Thanks
>>>>>
>>>>> Chris
>>>>>
>>>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>>>> entities not being enhanced - I verified that with javap.
>>>>>
>>>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all previous
>
>

Re: JPA component throwing "Attempt to cast instance [Ljava.lang.Object" *** PROBLEM SOLVED ***

Posted by Babak Vahdat <ba...@swissonline.ch>.

Am 16.01.13 01:07 schrieb "Chris Wolf" unter <cw...@gmail.com>:

>It was me not RTFM more carefully.  Sorry about that.  On the main
>Camel-JPA page it mentions a query option
>called "consumer.resultClass" which can be used to define the result
>class for a native query.  So when I added that,
>it all worked.
>
>Otherwise, without "consumer.resultClass", the native query returns
>List<Object[]>.
>
>But here's the thing - if I'm already indicating the entity class in
>the "scheme-specific-part" of the URI, (or entityType option)
>then why must it be specified again?  Seems redundant and I think
>seeing it there lulled me into thinking that the return
>type was defined, even for a native query.

It was my bad to not read through the thread before replying but happy to
see you found the solution by yourself.

Regarding your question why you should "repeat" yourself using the
"consumer.resultClass" option, well without using that option the
JpaConsumer makes use of:

  EntityManager.createNativeQuery(nativeQuery);

Which it's returned Query execution delivers List<Object[]> (See JPA 2
spec. 3.8.6), however with that option being specified it makes use of:

  EntityManager.createNativeQuery(nativeQuery, myEntityClass);

API which then returns List<myEntityClass>. So the reason is the way how
the native queries by the JPA API itself works.

Babak


>
>Thanks again,
>
>    -Chris
>
>On Tue, Jan 15, 2013 at 3:22 PM, Chris Wolf <cw...@gmail.com> wrote:
>> I upgraded to OpenJPA-2.2.1.  Still have the same issue.
>>
>>
>>
>> Here's the route, followed by console output, followed by entities
>> code.  BTW, I notice that the data type of Body coming out
>> of the jpa endpoint is of type Object[], I think this is part of the
>> problem, because I put a breakpoint on line 159 in JpaConsumer,
>> which is:
>>
>> getDeleteHandler().deleteObject(entityManager, result);
>>
>> ...and that  "result" is of type Object[] where each element is a
>> field value of the entity cooresponding to the
>> MarketData entity but it's NOT of type MarketData - hence the cast
>> exception when EntityManager.remove() is called.
>>
>> Thanks Claus and Christian,
>>
>>     -Chris
>>
>>
>>
>>
>>
>> 
>>from("jpa:entities.MarketData?persistenceUnit=marketdata&consumeDelete=tr
>>ue&consumer.nativeQuery=select
>> * from market_data where rownum < 10")
>>                 
>>.to("log:test.camel?showAll=true&multiline=true&level=INFO")
>>                 .to("mock:foo");
>>
>> 1158  marketdata  INFO   [Camel (camel-1) thread #1 -
>> jpa://entities.MarketData] openjpa.Runtime - Starting OpenJPA 2.2.1
>> 1236  marketdata  INFO   [Camel (camel-1) thread #1 -
>> jpa://entities.MarketData] openjpa.jdbc.JDBC - Using dictionary class
>> "org.apache.openjpa.jdbc.sql.OracleDictionary".
>> 3661 [Camel (camel-1) thread #1 - jpa://entities.MarketData] INFO
>> test.camel - Exchange[
>> , Id:ID-cwolf-55710-1358279796309-0-2
>> , ExchangePattern:InOnly
>> , 
>>Properties:{CamelToEndpoint=log://test.camel?level=INFO&multiline=true&sh
>>owAll=true,
>> CamelBatchComplete=true, CamelBatchSize=1, CamelCreatedTimestamp=Tue
>> Jan 15 14:56:39 EST 2013, CamelBatchIndex=0}
>> , 
>>Headers:{CamelJpaTemplate=org.springframework.orm.jpa.JpaTemplate@1e99db4
>>,
>> breadcrumbId=ID-cwolf-55710-1358279796309-0-1}
>> , BodyType:Object[]
>> , Body:[Ljava.lang.Object;@a1e2da
>> , Out: null
>> ]
>> 3272 [Camel (camel-1) thread #1 - jpa://entities.MarketData] WARN
>> org.apache.camel.component.jpa.JpaConsumer - Error processing last
>> message due: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>> Ensure that it has been enhanced.
>> FailedObject: [Ljava.lang.Object;@1cfd3b2. Will commit all previous
>> successful processed message, and ignore this last failure.
>> javax.persistence.PersistenceException: <openjpa-2.2.1-r422266:1396819
>> nonfatal user error> org.apache.openjpa.persistence.ArgumentException:
>> Attempt to cast instance "[Ljava.lang.Object;@1cfd3b2" to
>> PersistenceCapable failed.  Ensure that it has been enhanced.
>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>         at 
>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:102
>>)
>>         at 
>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1$1.doInJpa
>>(JpaTemplateTransactionStrategy.java:82)
>>         at 
>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:183)
>>         at 
>>org.springframework.orm.jpa.JpaTemplate.execute(JpaTemplate.java:146)
>>         at 
>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy$1.doInTrans
>>action(JpaTemplateTransactionStrategy.java:80)
>>         at 
>>org.springframework.transaction.support.TransactionTemplate.execute(Trans
>>actionTemplate.java:130)
>>         at 
>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(Jpa
>>TemplateTransactionStrategy.java:78)
>>         at 
>>org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75)
>>         at 
>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.j
>>ava:139)
>>         at 
>>org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.jav
>>a:91)
>>         at 
>>java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
>>         at 
>>java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317
>>)
>>         at 
>>java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
>>         at 
>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.acce
>>ss$101(ScheduledThreadPoolExecutor.java:98)
>>         at 
>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runP
>>eriodic(ScheduledThreadPoolExecutor.java:180)
>>         at 
>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(
>>ScheduledThreadPoolExecutor.java:204)
>>         at 
>>java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor
>>.java:886)
>>         at 
>>java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav
>>a:908)
>>         at java.lang.Thread.run(Thread.java:662)
>> Caused by: <openjpa-2.2.1-r422266:1396819 nonfatal user error>
>> org.apache.openjpa.persistence.ArgumentException: Attempt to cast
>> instance "[Ljava.lang.Object;@1cfd3b2" to PersistenceCapable failed.
>> Ensure that it has been enhanced.
>> FailedObject: [Ljava.lang.Object;@1cfd3b2
>>         at 
>>org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.
>>java:4667)
>>         at 
>>org.apache.openjpa.kernel.BrokerImpl.cascadeTransient(BrokerImpl.java:268
>>3)
>>         at 
>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2771)
>>         at 
>>org.apache.openjpa.kernel.BrokerImpl.delete(BrokerImpl.java:2742)
>>         at 
>>org.apache.openjpa.kernel.DelegatingBroker.delete(DelegatingBroker.java:1
>>102)
>>         at 
>>org.apache.openjpa.persistence.EntityManagerImpl.remove(EntityManagerImpl
>>.java:730)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at 
>>sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java
>>:39)
>>         at 
>>sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorI
>>mpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at 
>>org.springframework.orm.jpa.JpaTemplate$CloseSuppressingInvocationHandler
>>.invoke(JpaTemplate.java:425)
>>         at $Proxy14.remove(Unknown Source)
>>         at 
>>org.apache.camel.component.jpa.JpaConsumer$3.deleteObject(JpaConsumer.jav
>>a:337)
>>         at 
>>org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:
>>159)
>>         at 
>>org.apache.camel.component.jpa.JpaConsumer$1.doInJpa(JpaConsumer.java:97)
>>         ... 18 more
>>
>>
>> Here is the parent entity (which has collection of child entities)
>>
>> package entities;
>>
>> import java.io.Serializable;
>> import javax.persistence.*;
>> import java.math.BigDecimal;
>> import java.util.Date;
>> import java.util.Set;
>>
>>
>> /**
>>  * The persistent class for the MARKET_DATA database table.
>>  *
>>  */
>> @Entity
>> @Table(name="MARKET_DATA")
>> public class MarketData implements Serializable {
>>         private static final long serialVersionUID = 1L;
>>         private long marketDataId;
>>         private String currencyCode;
>>         private Date dataDate;
>>         private BigDecimal lastPrice;
>>         private BigDecimal lastUpdatedPrice;
>>         private String name;
>>         private String requestId;
>>         private String requestIdType;
>>         private String subType;
>>         private String type;
>>         private String vendorId;
>>         private String vendorName;
>>         private Set<RiskFactor> riskFactors;
>>
>>     public MarketData() {
>>     }
>>
>>
>>         @Id
>>         @SequenceGenerator(name="MARKET_DATA_MARKETDATAID_GENERATOR",
>> sequenceName="MARKET_DATA_ID_SEQ")
>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>> generator="MARKET_DATA_MARKETDATAID_GENERATOR")
>>         @Column(name="MARKET_DATA_ID", unique=true, nullable=false,
>>precision=19)
>>         public long getMarketDataId() {
>>                 return this.marketDataId;
>>         }
>>
>>         public void setMarketDataId(long marketDataId) {
>>                 this.marketDataId = marketDataId;
>>         }
>>
>>
>>         @Column(name="CURRENCY_CODE", length=3)
>>         public String getCurrencyCode() {
>>                 return this.currencyCode;
>>         }
>>
>>         public void setCurrencyCode(String currencyCode) {
>>                 this.currencyCode = currencyCode;
>>         }
>>
>>
>>     @Temporal( TemporalType.DATE)
>>         @Column(name="DATA_DATE")
>>         public Date getDataDate() {
>>                 return this.dataDate;
>>         }
>>
>>         public void setDataDate(Date dataDate) {
>>                 this.dataDate = dataDate;
>>         }
>>
>>
>>         @Column(name="LAST_PRICE", precision=20, scale=4)
>>         public BigDecimal getLastPrice() {
>>                 return this.lastPrice;
>>         }
>>
>>         public void setLastPrice(BigDecimal lastPrice) {
>>                 this.lastPrice = lastPrice;
>>         }
>>
>>
>>         @Column(name="LAST_UPDATED_PRICE", precision=20, scale=4)
>>         public BigDecimal getLastUpdatedPrice() {
>>                 return this.lastUpdatedPrice;
>>         }
>>
>>         public void setLastUpdatedPrice(BigDecimal lastUpdatedPrice) {
>>                 this.lastUpdatedPrice = lastUpdatedPrice;
>>         }
>>
>>
>>         @Column(length=100)
>>         public String getName() {
>>                 return this.name;
>>         }
>>
>>         public void setName(String name) {
>>                 this.name = name;
>>         }
>>
>>
>>         @Column(name="REQUEST_ID", length=50)
>>         public String getRequestId() {
>>                 return this.requestId;
>>         }
>>
>>         public void setRequestId(String requestId) {
>>                 this.requestId = requestId;
>>         }
>>
>>
>>         @Column(name="REQUEST_ID_TYPE", length=20)
>>         public String getRequestIdType() {
>>                 return this.requestIdType;
>>         }
>>
>>         public void setRequestIdType(String requestIdType) {
>>                 this.requestIdType = requestIdType;
>>         }
>>
>>
>>         @Column(name="SUB_TYPE", length=100)
>>         public String getSubType() {
>>                 return this.subType;
>>         }
>>
>>         public void setSubType(String subType) {
>>                 this.subType = subType;
>>         }
>>
>>
>>         @Column(name="\"TYPE\"", length=100)
>>         public String getType() {
>>                 return this.type;
>>         }
>>
>>         public void setType(String type) {
>>                 this.type = type;
>>         }
>>
>>
>>         @Column(name="VENDOR_ID", length=50)
>>         public String getVendorId() {
>>                 return this.vendorId;
>>         }
>>
>>         public void setVendorId(String vendorId) {
>>                 this.vendorId = vendorId;
>>         }
>>
>>
>>         @Column(name="VENDOR_NAME", length=100)
>>         public String getVendorName() {
>>                 return this.vendorName;
>>         }
>>
>>         public void setVendorName(String vendorName) {
>>                 this.vendorName = vendorName;
>>         }
>>
>>
>>         //bi-directional many-to-many association to RiskFactor
>>     @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,
>> CascadeType.REFRESH})
>>         @JoinTable(
>>                 name="MARKET_DATA_RISK_FACTOR"
>>                 , joinColumns={
>>                         @JoinColumn(name="MARKET_DATA_ID",
>>nullable=false)
>>                         }
>>                 , inverseJoinColumns={
>>                         @JoinColumn(name="RISK_FACTOR_ID",
>>nullable=false)
>>                         }
>>                 )
>>         public Set<RiskFactor> getRiskFactors() {
>>                 return this.riskFactors;
>>         }
>>
>>         public void setRiskFactors(Set<RiskFactor> riskFactors) {
>>                 this.riskFactors = riskFactors;
>>         }
>> }
>>
>>
>>
>> package entities;
>>
>> import java.io.Serializable;
>> import javax.persistence.*;
>> import java.math.BigDecimal;
>> import java.util.Date;
>> import java.util.Set;
>>
>>
>> /**
>>  * The persistent class for the RISK_FACTOR database table.
>>  *
>>  */
>> @Entity
>> @Table(name="RISK_FACTOR")
>> public class RiskFactor implements Serializable {
>>         private static final long serialVersionUID = 1L;
>>         private long riskFactorId;
>>         private Date dataDate;
>>         private String name;
>>         private BigDecimal seq;
>>         private BigDecimal seq2;
>>         private String type;
>>         private BigDecimal value;
>>         private BigDecimal value2;
>>         private Set<MarketData> marketData;
>>
>>     public RiskFactor() {
>>     }
>>
>>
>>         @Id
>>         @SequenceGenerator(name="RISK_FACTOR_RISKFACTORID_GENERATOR",
>> sequenceName="RISK_FACTOR_ID_SEQ")
>>         @GeneratedValue(strategy=GenerationType.SEQUENCE,
>> generator="RISK_FACTOR_RISKFACTORID_GENERATOR")
>>         @Column(name="RISK_FACTOR_ID", unique=true, nullable=false,
>>precision=19)
>>         public long getRiskFactorId() {
>>                 return this.riskFactorId;
>>         }
>>
>>         public void setRiskFactorId(long riskFactorId) {
>>                 this.riskFactorId = riskFactorId;
>>         }
>>
>>
>>     @Temporal( TemporalType.DATE)
>>         @Column(name="DATA_DATE")
>>         public Date getDataDate() {
>>                 return this.dataDate;
>>         }
>>
>>         public void setDataDate(Date dataDate) {
>>                 this.dataDate = dataDate;
>>         }
>>
>>
>>         @Column(length=100)
>>         public String getName() {
>>                 return this.name;
>>         }
>>
>>         public void setName(String name) {
>>                 this.name = name;
>>         }
>>
>>
>>         @Column(precision=1)
>>         public BigDecimal getSeq() {
>>                 return this.seq;
>>         }
>>
>>         public void setSeq(BigDecimal seq) {
>>                 this.seq = seq;
>>         }
>>
>>
>>         public BigDecimal getSeq2() {
>>                 return this.seq2;
>>         }
>>
>>         public void setSeq2(BigDecimal seq2) {
>>                 this.seq2 = seq2;
>>         }
>>
>>
>>         @Column(name="\"TYPE\"", length=100)
>>         public String getType() {
>>                 return this.type;
>>         }
>>
>>         public void setType(String type) {
>>                 this.type = type;
>>         }
>>
>>
>>         @Column(name="\"VALUE\"", precision=20, scale=4)
>>         public BigDecimal getValue() {
>>                 return this.value;
>>         }
>>
>>         public void setValue(BigDecimal value) {
>>                 this.value = value;
>>         }
>>
>>
>>         @Column(precision=20, scale=4)
>>         public BigDecimal getValue2() {
>>                 return this.value2;
>>         }
>>
>>         public void setValue2(BigDecimal value2) {
>>                 this.value2 = value2;
>>         }
>>
>>
>>         //bi-directional many-to-many association to MarketData
>>         @ManyToMany(mappedBy="riskFactors")
>>         public Set<MarketData> getMarketData() {
>>                 return this.marketData;
>>         }
>>
>>         public void setMarketData(Set<MarketData> marketData) {
>>                 this.marketData = marketData;
>>         }
>>
>> }
>> On Sat, Jan 12, 2013 at 6:31 AM, Christian Müller
>> <ch...@gmail.com> wrote:
>>> And by the way, we are using OpenJPA 2.2.1 instead of 2.2.0, which you
>>>are
>>> using. Can you upgrade?
>>>
>>> Best,
>>> Christian
>>>
>>> On Fri, Jan 11, 2013 at 8:23 PM, Chris Wolf <cw...@gmail.com>
>>>wrote:
>>>
>>>> I have a JPA endpoint setup as a consumer, just performing a basic
>>>> query.  If I have consumeDelete=false configured,
>>>> then it works and I see the entities.  When consumeDelete=false is not
>>>> configured (default is to remove), then the error
>>>> occurs upon JpaTemplate calling  EntityManagerImpl.remove(arg) - but
>>>> "arg" is of type Object[] - not the entity.
>>>>
>>>> Second issue is I'd like the route to just perform the query once.
>>>> As it is, invokes the query in a loop.
>>>>
>>>> Thanks
>>>>
>>>> Chris
>>>>
>>>> P.S. the EntityManagerImpl.remove(arg) issue is not due to the
>>>> entities not being enhanced - I verified that with javap.
>>>>
>>>> FailedObject: [Ljava.lang.Object;@1e3a0ec. Will commit all previous