Eclipselink -Glassfish project Object is not a known entity type error - jpa

In a JSF 2.1 - Spring 3.1 integrated project.I m trying to handle transaction by container i m using eclipselink 2.3.2 ,Glassfish 3.1.2 and Maven on my project and working on Netbeans IDE 7.2 .
At service layer i injected entity manager by the code below and on debug it seems ok .
#Inject
public void setEntityManager() {
EntityManagerFactory emfactory =Persistence.createEntityManagerFactory
("E_DefterManagementPU");
this.em = emfactory.createEntityManager();
But after i filled the entity named EfaFunctions and try to persist with
em.persist(EfaFunctions);
it gives this error
java.lang.IllegalArgumentException: Object: org.eclipse.persistence.internal.jpa.EntityManagerImpl#599ebbf6
is not a known entity type.
But in **persistence.xml ** i have following nodes
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>EFA</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
My entity project location is com.edefter.entity.EfaFunctions ;not the location specified in error .Actually there is an answer written by Pascal in this link
but my generation strategy is none and my entites were generated from Database by netbeans .I need some experts advice . Thanks in Advance
I deleted the
#Table(name="EFA_FUNCTIONS")
annotation from top of Entity ,but #Entity still stays.
The error is gone but then the query starts as
INSERT INTO EFAFUNCTIONS
without underscore but i need
INSERT INTO EFA_FUNCTIONS
,becouse of it the data did not inserted . Why eclipselink gives error for #Table annotation and despite there is no table like EFAFUNCTIONS why it doesnt give any error

I solved the problem , As i mentioned in question i had generated Entities from Database via Netbeans,so that i didn't suspect the entity format.I had worked before hibernate as ORM and hibernate plus DB2 or MYSQL.These combinations didnt give an error with same usage.But with the combination Eclipselink - Oracle DB #Entity annotation has to be parameter as written below
#Entity(name="entityName")
#Table(name="TableName")
Thanks for comment.

Why would you try to persist an EntityManager ? Much better to pass in (to em.persist) an Entity (one of those classes tagged as #Entity)

I had a similar problem, when trying to persist an object of an entity class by calling persist() on the entitymanager:
java.lang.IllegalArgumentException: Object: entities.Documents[ id=null ] is not a known entity type.
it turned out that the name of the persistence unit declared in the persistence.xml in the line
<persistence-unit name="my-pu" transaction-type="RESOURCE_LOCAL">
was diffrent from the name I used when declaring the Entity Manager Factory in the java code:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("my-persistenceunit");
After correcting both names to the same name, calling persist() worked as expected.

Related

JPA EclipseLink HistoryPolicy example

I am following the example provided here by eclipselink.
When I start my tests, it fails with:
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.1.v20171221-bd47e8f):
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: relation "event_history" does not exist.
The framework isn't creating the table as I would expect. I have the following configuration:
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
From this link, I don't feel it's necessary to add the DescriptorCustomizer class to the persistence.xml file. But I may be wrong.
My question is, do I have to create the table manually? Or I am doing something wrong? The examples I found relative to the feature are quiet poor.
Some solutions are discussed in eclipse link forum.
Clovis Wichoski CLA Friend 2016-01-02 15:29:19 EST
The problem still occurs with 2.6.2
Follow a StringTemplate to be used to easy the creation by hand (for Postgres database)
CREATE TABLE <tableName>_audit (
LIKE <tableName> EXCLUDING ALL,
audit_date_start timestamp,
audit_date_end timestamp
)
Here is another possible solution:
Peter Hansson CLA Friend 2016-03-25 05:30:42 EDT
Yes, I've had the same issue.
I've explored a couple of avenues in order to get EclipseLink to generate the history tables for me (so that they always reflect their base table). I haven't been able to come up with a method that would work, less one that would be db agnostic.
I do believe the only way to solve this is in the core of EclipseLink, for example by adding a new annotation, #HistoryTable.
I'm thinking something along the lines of the following:
Suppose you have base class, Person:
#Entity
public class Person {
#Id
private Long personId;
private String firstName;
private String lastName;
..
}
Then we could define a history entity for that entity as follows:
#Entity
#HistoryTable(base=Person.class, primaryKeyFields="personId,rowStartTime")
public class PersonHist {
// Add here the extra fields/columns that should exist for the
// history table.
private Date rowStartTime;
private Date rowEndTime;
..
}
The #HistoryTable annotation would replicate all fields from the base entity, including most field annotations, except for annotations related to relations, which wouldn't be relevant on the history table.
By definition the history table's primary key will always be a composite of columns in the base table, typically it will be like in the example. In the example the PersonHist entity will think it has an #Id notation on fields personId and rowStartTime. (yeah, this area needs more brain work :-))

Why are #OneToMany relationships are duplicated?

I have a 'save()' method inside a Session EJB (UpdateService) which persists an JPA Entity Bean.
The method first removes all existing #OneToMany relations to the Entity Bean. Than the method creates new relations and persists them. This all works so far as expected.
But now I have a situation, where another Session EJB (SuperService) which is calling my first Session Bean (UpdateService) needs to update a specific JPA Entity Bean twice. So during one transaction the method UpdateService.save() is called twice for the same entity.
I can see, that in this case the second call of UpdateService.save() did not recognize that the first call has created new relationship (which - as a result, will not be removed) and so it creates an additional relationship. As a result the relationship is doubled. The magic thing is, that other data which is part of attributes of my entity bean are already updated in the second call. It seems that only the pending new relationships are not removeable.
I played already with setting the TransactionIsolation to TRANSACTION_READ_UNCOMMITTED, but with no effect.
So my question is: how can I see that my entity has uncommited new relationships so that I can remove them?
I am running EclipseLink 2.5 on WildFly with MySQL.
This is a simplified part of my EJB code:
....
manager.setFlushMode(FlushModeType.COMMIT);
...
activeEntity = manager.find(Entity.class, sID);
// remove current TextItem List
for (TextItem aItem : activeEntity.getTextItems())
manager.remove(aItem);
activeEntity.getTextItems().clear();
..
// update the relationships
for (Object asingleValue : valueList) {
TextItem newItem = new TextItem(index.getName(),
asingleValue.toString());
manager.persist(newItem);
activeEntity.getTextItems().add(newItem);
}
manager.flush();
manager.detach(activeEntity);
return statusResult;

JPA EclipseLink table creation order

I have a working project that uses JPA to persist data on MySQL (EclipseLink as provider). Recently I wanted to drop the database and create it again with the tables via Eclipse => EclipseLink 'Generate tables from entities'. I also have the persistence.xml updated (first generated automatically, then modified manually to narrow down on this problem).
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>xxx.entity.options.Difficulty</class>
<class>xxx.entity.options.Options</class>
(Omitted the rest since it is ok otherwise => it is working in general)
The problem is that when I generate the tables I get the error:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'xxx.DIFFICULTY' doesn't exist
Error Code: 1146
(The entity classes have table names defined:
#Entity
#Table(name = "DIFFICULTY"))
If I comment out the 'Options' from persistence.xml, the 'DIFFICULTY' table gets created ok. Then uncommenting 'Options' again and re-generating the tables => the 'OPTIONS' table will be created also (Options has #ManyToOne association with the Difficulty).
In the persistence.xml I have
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
as I am still developing.
In the Options class I have
#ManyToOne(optional = false, cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
private Difficulty difficulty = null;
(Many Options are suppose to have the same Difficulty selected, so none really owns one. I hope this is correct?)
After The Difficulty and Options tables were created successfully, I was able to re-create the rest of the database tables.
The question is that should I (be able to) specify the order in which the tables are created?
Have I something wrong with the #ManyToOne association?
Already spent couple of hours on this issue, but couldn't figure it out what is the problem.
Sorry for the long text, I just try to explain the whole situation.
Last time I received 'tl; dr;' answer (didn't know by that time what it meant), I spent 6 hours looking the wrong thing, so please do not bother to answer in such case.
If you look at the exceptions stack, you'll see it is coming from your entity's default constructor. This constructor is trying to issue a query by obtaining an entitymanager, and is failing because the table it needs doesn't exist yet. When you create that one table, the constructor can query it, which allows everything to proceed.
You should not have business logic in your default constructor. This is used by the provider, and is getting called during deployment before DDL. Removing that will resolve the issue.
Are you changing the class/schema in between your last create? It could be that you have added or removed new relationships, so EclipseLink is not able to drop the old constraints.
For drop-and-create-tables EclipseLink will basically do the following,
drop known constraints
drop known tables
create known tables
create known constraints
In the latest release EclipseLink will try a couple drop passes to try and handle unknown constraints, but the best method for a rapidly changing development schema would be to drop the entire schema in between deployments.

How to Sync Entity Bean with Database After Trigger Update

PostgreSQL 9.1
Glassfish 3.1.2.2
Firefox 10.0.0.7
Linux
I am using JPA to persist entities in PostgreSQL. However, there is one table (named Position) which is populated by triggers and I use an entity of that table which acts as a read only. The entity never persist data into this table as it's loaded and manipulated from the triggers. I can load the data into my managed bean and view the Position table data fine.
The problem I have is that once the database (Position table) has been modified by the triggers, when the Position table is queried again, the values are still the same. The Position entity still contains the old values and have not reloaded.
Here is the bean which handles the Position entity. I added em.flush() which didn't help and wasn't sure how to use em.refresh() in this way. And actually, how would syncing help anyways since it doesn't know what I want to sync to without a query.
Any help much appreciated.
The EJB ...
#Stateless
public class PositionBean implements IPosition {
#PersistenceContext(unitName="positionbean-pu")
private EntityManager em;
public Position getPositionById(Integer posId) {
Position pos = null;
try {
pos = (Position) em.createNamedQuery("findPosition")
.setParameter("posId", posId).getSingleResult();
}
catch (Exception e) {
throw new EJBException(e.getMessage());
}
return pos;
}
The entity bean ...
#Entity
#SequenceGenerator(name="posIdGen", initialValue=10000,
sequenceName="pos_seq", allocationSize=1)
#NamedQuery(name="findPosition",
query="SELECT p FROM Position p WHERE p.posId = :posId")
#Table(name="Position")
public class Position implements Serializable {
// ...
persistence.xml
<persistence-unit name="positionbean-pu" transaction-type="JTA">
<jta-data-source>jdbc/postgreSQLPool</jta-data-source>
</persistence-unit>
In case anyone runs into this, I learned how to use refresh() and this fixed my problem.
pos = (Position) em.createNamedQuery("findPosition")
.setParameter("posId", posId).getSingleResult();
em.refresh(pos);
In my opinion the correct way to create a read only entity that is updated "externally" is as follows:
Do use field based annotation for the entity class by setting annotation #Access to AccessType.FIELD (or remove the annotation because it is the default access type) as stated out in this answer. Also propose public getters only as stated out in this answer. This prevents the entity from beeing modified within the application.
Enable selective shared cache mode in persistence.xml file and add annotation #Cacheable(false) to the entity class as stated out in this answer. This forces JPA to always load the entity from the persistence layer when you call EntityManager#find(...).

Open JPA : An error occurred while parsing the query filter 'MY_QUERY' Error message: No field named "accessAuthorizationVs" in class "MyEntityClass"

I have configured it in my Rational Software Architect 8.0.4, by enabling the JPA 1.0 facet. It autogenerates almost all my entity classes except for the id's. So I manually add them. I am trying to query a simple table APP_USER that has one-to-many relation to ACCESS_AUTHORIZATION table. See below for the configurations and entity classes.
When I try to execute a simple named query which is
SELECT a.accessAuthorizationVs, a.empName, a.userCnum FROM AppUserEntity a WHERE a.userCnum = :userCnum
It throws an exception
**org.apache.openjpa.persistence.ArgumentException: An error occurred while parsing the query filter "SELECT a.accessAuthorizationVs, a.empName, a.userCnum FROM AppUserEntity a WHERE a.userCnum = :userCnum". Error message: No field named "accessAuthorizationVs" in class "class com.xxx.xxx.xxx.services.integration.entity.AppUserEntity".**
at org.apache.openjpa.kernel.exps.AbstractExpressionBuilder.parseException(AbstractExpressionBuilder.java:118)
at org.apache.openjpa.kernel.exps.AbstractExpressionBuilder.traversePath(AbstractExpressionBuilder.java:284)
at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getPath(JPQLExpressionBuilder.java:1382)
at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getPathOrConstant(JPQLExpressionBuilder.java:1337)
Here's a snapshot of my persistence.xml:
Can anyone guide me what I am doing wrong here? The field by that name is clearly defined in my entity class. Also I would like to mention that I had to enhance the classes[followed this] as there was an earlier error about classes not being enhanced.
When you create a named query in OpenJPA, remember that you are writing JPQL, not native SQL. The syntax is similar, but a little different.
In this case, I suggest changing your named query to the following:
SELECT a FROM AppUserEntity a WHERE a.userCnum = :userCnum
This will return an object of the AppUserEntity class which will include the set of AccessAuthorizationV objects (lazy loaded by default).
For more details, see the JPQL Language Reference.