0
votes

I'm using GlassFish 3.1.2 with Eclipse 4.2. If I specify a JTA transaction type, with a jta-data-source, I can happily add a new class, which will be read as entity if I put the @Entity annotation.
Now, if I change the transaction type to RESOURCE_LOCAL, the data source to non-jta, and I add the necessary code to retrieve the EntityManager and the EntityTransaction where I will call begin() and commit(), I get an error: my entity is not a known entity type. To solve the problem I have to add my entity to the classes listed in the persistence.xml.
Now, that solves my problem, but I don't understand why. Per specification, all the annotated classes in the persistence root should be managed by the persistence unit, unless exclude-unlisted-classes is specified. So the fact that I change the transaction type to RESOURCE_LOCAL shouldn't be a difference.
Anybody has an answer?

EDIT: Some extra information. I have some simple code that causes the error, it's to save a currency in the database. The persist is done in the form:

@Named( "newCurrencyForm2" )
@RequestScoped
public class NewCurrencyForm
{
    public Currency getCurrency()
    {
        return currency;
    }

    public void createCurrency()
    {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory( "foo" );
        EntityManager manager = factory.createEntityManager();
        EntityTransaction transaction = manager.getTransaction();

        transaction.begin();
        manager.persist( currency );
        manager.getTransaction().commit();
    }

    private Currency currency = new Currency();
}

and the stack trace is:

java.lang.IllegalArgumentException: Object: com.test.Currency@24cce2eb is not a known entity type. at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4169) at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:440) at com.test.NewCurrencyForm.createCurrency(NewCurrencyForm.java:26) at com.test.NewCurrencyForm$Proxy$_$$WeldClientProxy.createCurrency(NewCurrencyForm$Proxy$$$_WeldClientProxy.java) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at com.sun.el.parser.AstValue.invoke(AstValue.java:254) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) at javax.faces.component.UICommand.broadcast(UICommand.java:315) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:722)

2
What has transaction type got to do with specifying classes in persistence.xml? Answer : Nothing, they are different concepts.DataNucleus
I know that, thanks. That's the reason why I asked the question. I'm not sure of what you are implyingtroublemaker
Simply confirming what you expected, that it is a misnomer (at least from the spec point of view) to read anything into transaction type. Obviously there may be some implementation-specific "feature" in there, but best to actually define what persistence operation you use where you get entity is not a known entity type (and the stack trace), and then the implementation in question can answer whyDataNucleus
Yeah, I was thinking about something implementation specific, which is why I specified the application server and the development environment. Okay, I'll post some some informationtroublemaker

2 Answers

1
votes

My guess as to what is occurring is the when you have your transaction type as JTA your are injecting, or using a container managed persistence unit. But, when you are using RESOURCE_LOCAL you are managing your own persistence unit, perhaps using Persistence.createEntityManagerFactory().

I'm also guessing you never call close() on your EntityManagerFactory, and are redeploying your persistence unit to a live server.

My guess is that your RESOURCE_LOCAL config will work if you restart your server, or if you close() your EntityManagerFactory before redeploying. What is most likely occurring is that the old persistence unit with the old classes is sticking around, so does not have the new classes.

Also ensure you are rebuilding your jar and redeploying correctly when you make your changes.

0
votes

Analysis

Persistence unit's transaction type has nothing to do with managed persistable classes.

Managed Persistable Classes

JPA requires registration of all the user defined persistable classes (entity classes, embeddable classes and mapped superclasses), which are referred to by JPA as managed classes, as part of a persistence unit definition.

Solution

If your Currency class is a JPA managed persistable class, then you need to specify fully qualified name of this class in your persistence.xml:

<class>com.test.Currency</class>

This will register it within persistence unit and will recognize it as a known entity type.