Are you using the same version of OpenJPA to enhance your classes that you're using at runtime?
On Tue, Jan 15, 2013 at 5:11 PM, Chris Wolf <[email protected]> wrote: > Babak, > > Thanks for the detailed reply, but if you look at my first post on > this thread, I mentioned that that error message concerning > enhancement is misleading. If I configure "consumeDelete=false", > there's no error - the entities are created by JPA. > I also mentioned I verified enhancement by observing the added fields, > methods and interfaces via the "javap" (decompiler) tool. > > I didn't know about the test-enhance goal, so that was good to learn, thanks. > (my entities are under main/java, so I just use the "enhance" goal) > > -Chris > > > On Tue, Jan 15, 2013 at 4:05 PM, Babak Vahdat > <[email protected]> wrote: >> >> >> Am 15.01.13 21:22 schrieb "Chris Wolf" unter <[email protected]>: >> >>>I upgraded to OpenJPA-2.2.1. Still have the same issue. >> >> Hi >> >> The problem you're facing is that the byte-code of your JPA entity has not >> been enhanced, see your stack trace where it says "Ensure that it has been >> enhanced." Also take a look at the source where that exception is thrown: >> >> org.apache.openjpa.kernel.BrokerImpl.assertPersistenceCapable(BrokerImpl.ja >> va:4667) >> >> When enhancement gets done properly then the byte code of your entity >> class gets instrumentalized to implement the interface >> org.apache.openjpa.enhance.PersistenceCapable (this's of course in case of >> OpenJPA). >> >> No matter which JPA provider you make use of (OpenJPA, Hibernate or >> Eclipselink) @ runtime you should make sure that the entity class byte >> code has been enhanced/weaved properly. This can be done either statically >> or dynamically. Recently I added a note about this on the Camel JPA >> component documentation which could be helpful for your use case. See the >> blue box at the bottom here: >> >> http://camel.apache.org/jpa.html >> >> In that box there's also a link pointing to the corresponding OpenJPA >> documentation about this. You can also look at the camel-jpa POM itself to >> see how the static enhancement is done. However in your case you would >> need to make use of the "enhance" goal and not "test-enhance". >> >> Babak >> >>> >>> >>> >>>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=tru >>>e&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&sho >>>wAll=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.doInTransa >>>ction(JpaTemplateTransactionStrategy.java:80) >>> at >>>org.springframework.transaction.support.TransactionTemplate.execute(Transa >>>ctionTemplate.java:130) >>> at >>>org.apache.camel.component.jpa.JpaTemplateTransactionStrategy.execute(JpaT >>>emplateTransactionStrategy.java:78) >>> at >>> org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:75) >>> at >>>org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.ja >>>va: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.acces >>>s$101(ScheduledThreadPoolExecutor.java:98) >>> at >>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPe >>>riodic(ScheduledThreadPoolExecutor.java:180) >>> at >>>java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(S >>>cheduledThreadPoolExecutor.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.j >>>ava: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:11 >>>02) >>> 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(DelegatingMethodAccessorIm >>>pl.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:1 >>>59) >>> 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 >>><[email protected]> 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 <[email protected]> >>>>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 >> >>
