Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Eclipselink Extensible Entity throw java.lang.NoSuchFieldException
Eclipselink Extensible Entity throw java.lang.NoSuchFieldException [message #1224717] Fri, 27 December 2013 15:40 Go to next message
Barry Zhong is currently offline Barry ZhongFriend
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 Go to previous message
Barry Zhong is currently offline Barry ZhongFriend
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?
Previous Topic:Dynamic Moxy Exception for Enum Value Conversion
Next Topic:[ SOLVED ]JPA Question
Goto Forum:
  


Current Time: Fri Apr 26 06:33:11 GMT 2024

Powered by FUDForum. Page generated in 0.02709 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top