Eclipselink Extensible Entity throw java.lang.NoSuchFieldException [message #1224717] |
Fri, 27 December 2013 15:40 |
Barry Zhong Messages: 11 Registered: March 2013 |
Junior Member |
|
|
I am trying EclipseLink Extensible Entity Feature on Glassfish V4. And I did the following command to get the sample code:
git clone http://git.eclipse.org/gitroot/eclipselink/examples/mysports.git
But it cannot work, and then I update a few fixes and commit it into:
https://github.com/zhongdj/multitenency-eclipselink-samples-mysports
It is getting to work, but still cannot work well with Entity Extension.
persistence.xml is as following:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mysports" transaction-type="RESOURCE_LOCAL">
<provider>eclipselink.example.mysports.persistence.TenantPerEMFProvider</provider>
<non-jta-data-source>jdbc/mysports</non-jta-data-source>
<mapping-file>META-INF/local-eclipselink-orm.xml</mapping-file>
<class>eclipselink.example.mysports.application.model.Division</class>
<class>eclipselink.example.mysports.application.model.Team</class>
<class>eclipselink.example.mysports.application.model.Player</class>
<class>eclipselink.example.mysports.application.model.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<properties>
<!-- Logging Config -->
<property name="eclipselink.logging.level" value="FINE" />
<property name="eclipselink.logging.timestamp" value="false" />
<property name="eclipselink.logging.thread" value="false" />
<property name="eclipselink.logging.connection" value="false" />
<property name="eclipselink.logging.level.metadata" value="WARNING" />
<property name="eclipselink.logging.parameters" value="true" />
<property name="eclipselink.logging.session" value="false" />
<property name="eclipselink.logging.exceptions" value="false" />
<property name="eclipselink.logging.level.metadata" value="WARNING" />
<property name="eclipselink.jdbc.allow-native-sql-query"
value="true" />
<property name="eclipselink.metadata-source" value="eclipselink.example.mysports.application.admin.AdminMetadataSource" />
</properties>
</persistence-unit>
Fetched the ORMapping from AdminMetadataSource is as following:
<?xml version="1.0" encoding="UTF-8"?>
<orm:entity-mappings xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm org/eclipse/persistence/jpa/eclipselink_orm_2_5.xsd"
xmlns:orm="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5.0">
<orm:package>eclipselink.example.mysports.application.model</orm:package>
<orm:entity class="Division">
<orm:multitenant type="SINGLE_TABLE">
<orm:tenant-discriminator-column name="LEAGUE_ID" context-property="league" length="5"/>
</orm:multitenant>
<orm:attributes>
<orm:basic name="penaltyMinutes" access="VIRTUAL" attribute-type="java.lang.Integer">
<orm:column name="FLEX_2"/>
</orm:basic>
<orm:basic name="position" access="VIRTUAL" attribute-type="java.lang.String">
<orm:column name="FLEX_1"/>
</orm:basic>
</orm:attributes>
</orm:entity>
<orm:entity class="Team">
<orm:multitenant type="SINGLE_TABLE">
<orm:tenant-discriminator-column name="LEAGUE_ID" context-property="league" length="5"/>
</orm:multitenant>
<orm:attributes>
<orm:basic name="penaltyMinutes" access="VIRTUAL" attribute-type="java.lang.Integer">
<orm:column name="FLEX_2"/>
</orm:basic>
<orm:basic name="position" access="VIRTUAL" attribute-type="java.lang.String">
<orm:column name="FLEX_1"/>
</orm:basic>
</orm:attributes>
</orm:entity>
<orm:entity class="Player">
<orm:multitenant type="SINGLE_TABLE">
<orm:tenant-discriminator-column name="LEAGUE_ID" context-property="league" length="5"/>
</orm:multitenant>
<orm:attributes>
<orm:basic name="penaltyMinutes" access="VIRTUAL" attribute-type="java.lang.Integer">
<orm:column name="FLEX_2"/>
</orm:basic>
<orm:basic name="position" access="VIRTUAL" attribute-type="java.lang.String">
<orm:column name="FLEX_1"/>
</orm:basic>
</orm:attributes>
</orm:entity>
</orm:entity-mappings>
And the Player class is as following:
@Entity
@Table(name = "MYS_PLAYER")
@NamedQueries({
@NamedQuery(name="Player.findByTeam", query="SELECT p FROM Player p WHERE p.team.id = :team ORDER BY p.lastName, p.firstName"),
@NamedQuery(name="Player.findAll", query="SELECT p FROM Player p ORDER BY p.lastName, p.firstName")
})
@VirtualAccessMethods
@Multitenant
@TenantDiscriminatorColumn(name="LEAGUE_ID", contextProperty=MySportsConfig.LEAGUE_CONTEXT, length=5)
public class Player implements Extensible {
@Id
@GeneratedValue
@Column(name = "ID")
private int id;
...
/**
* Extended attributes
*/
@Transient
private Map<String, Object> attributes = new HashMap<String, Object>();
...
@SuppressWarnings("unchecked")
public <T> T get(String attributeName) {
return (T) this.attributes.get(attributeName);
}
public Object set(String attributeName, Object value) {
return this.attributes.put(attributeName, value);
}
...
And then I met this exception:
Caused by: Exception [EclipseLink-7215] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.ValidationException Exception Description: Could not load the field named [position] on the class [class eclipselink.example.mysports.application.model.Player_]. Ensure there is a corresponding field with that name defined on the class. Internal Exception: java.security.PrivilegedActionException: java.lang.NoSuchFieldException: position at org.eclipse.persistence.exceptions.ValidationException.invalidFieldForClass(ValidationException.java:2724) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.initializeCanonicalMetamodel(EntityManagerSetupImpl.java:3423) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.getMetamodel(EntityManagerSetupImpl.java:3387) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getMetamodel(EntityManagerFactoryDelegate.java:638) at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:548) at eclipselink.example.mysports.application.services.LeagueRepository.getAdditionalAttributes(LeagueRepository.java:367)
This is weird since 'position' is a VIRTUAL column, but eclipselink was searching from the static meta model.
I reviewed http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Extensible_Entities for several times, it seems to be very easy to work with Extensible Entity, what did I miss?
|
|
|
Re: Eclipselink Extensible Entity throw java.lang.NoSuchFieldException [message #1224934 is a reply to message #1224717] |
Sat, 28 December 2013 06:53 |
Barry Zhong Messages: 11 Registered: March 2013 |
Junior Member |
|
|
[NEW UPDATES]
I found after I remove those canonical metamodel classes (Player_.class) from ${glassfish-domain-dir}/applications/application-2.4.2-SNAPSHOT/WEB-INF/classes/eclipselink/example/mysports/application/model, and then those extensible fields can be displayed on web page. It seems that the @StaticMetamodel classes conflicts with Extensible Entity Features.
But the original sample code author was referencing those canonical metamodel classes to build queries such as:
/**
* Retrieve a player using its division, team name, and jersey number using
* JPA 2.0 criteria.
*/
public Player getPlayerByNumber(String division, String teamId, int number) {
EntityManager em = getEMF().createEntityManager();
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Player> query = qb.createQuery(Player.class);
Root<Player> player = query.from(Player.class);
Predicate numEqual = qb.equal(player.get(Player_.number), number);
Predicate teamEqual = qb.equal(player.get(Player_.team).get(Team_.name), teamId);
Predicate divEqual = qb.equal(player.get(Player_.team).get(Team_.division).get(Division_.name), division);
query.where(qb.and(numEqual, teamEqual, divEqual));
return em.createQuery(query).getSingleResult();
} finally {
em.close();
}
}
So those canonical meta model classes were obviously generated on purpose, but they conflicts with extensible entity feature in my runtime environments. What was I missing on configuration or something else?
|
|
|
Powered by
FUDForum. Page generated in 0.03465 seconds