简体   繁体   中英

JPA: Named Query of name: … not found

I'm developing a multitenacy application with JPA at my company. So I use the TABLE_PER_TENANT feature to separate the tenant specific data into different schemas. Pushing the data into the DB is no problem, that works fine. The problem is just reading the data from the DB, the application can't find my named queries.

I already tried different things:

  • Recompile and deploy application
  • Move persistence.xml into different folders
  • Checked error logs and debugged the whole app, couldn't find the reason for this
  • Had a look at the all possible solutions I could find on Google and tried them...

What am I missing here? Any ideas?

BaseObject.java

@MappedSuperclass
@Multitenant(MultitenantType.TABLE_PER_TENANT)
@TenantTableDiscriminator(type = TenantTableDiscriminatorType.SCHEMA, contextProperty="tenant.id")
public abstract class BaseObject {

    /**
     * The (globally unique) ID of the object.
     */
    @Id
    @Column(name = "GUID", length = 36)
    private String guid = UUID.randomUUID().toString();

    /**
     * The {@link Date} the object was created at.
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATION_DATE", updatable = false)
    private Date createdAt = null;

    /**
     * The {@link Date} the object was last modified at.
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "MODIFICATION_DATE")
    private Date lastModifiedAt = null;

    /**
     * ID of the user who created the object.
     */
    @Column(name = "CREATED_BY", updatable = false, length = 20)
    private String createdBy = null;

    /**
     * ID of the user who was the last to modify the object.
     */
    @Column(name = "MODIFIED_BY", length = 20)
    private String lastModifiedBy = null;

    // Methods...
}

Plant.java

@Entity
@Table(name = "PLANT_POLLUTION_DATA")
@NamedQueries({ @NamedQuery(name = "Plant.getPlants", query = "SELECT c FROM Plant c"),
                @NamedQuery(name = "Plant.getPlantById", query = "SELECT c FROM Plant c WHERE c.id = :id") })

@XmlRootElement(name = "plantlist")
@XmlAccessorType(XmlAccessType.FIELD)
public class Plant extends BaseObject implements Serializable {

    /**
     * The <code>serialVersionUID</code> of the {@link Plant} class.
     */
    private static final long serialVersionUID = 1L;

    @Column(name = "ID", length = 36, nullable = true)
    String id = null;

    @Column(name = "O3", length = 10, nullable = true)
    String o3 = null;

    @Column(name = "DATE_FIELD")
    java.sql.Date dateField = null;

    @Column(name = "location", length = 36, nullable = true)
    String location = null;

    // Methods...
}

NamedQuery call

String tenantId = getTenantId();
Map<String, String> props = new HashMap<String, String>();
props.put("tenant.id", tenantId);
EntityManager em = this.getEntityManagerFactory().createEntityManager(props);
Query query = em.createNamedQuery("Plant.getPlantById");
query.setParameter("id", id);
retVal = query.getResultList();

persistence.xml (located at "file.war/WEB-INF/classes/META-INF/persistence.xml")

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="pollutionmonitoring" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.company.cloud.samples.pollutionmonitoring.model.BaseObject</class>
        <class>com.company.cloud.samples.pollutionmonitoring.model.Plant</class>
        <properties>
            <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
        </properties>
    </persistence-unit>
</persistence>

I could just fix this problem myself by adding the following 2 lines of code:

...
EntityManager em = this.getEntityManagerFactory().createEntityManager(props);

em.getTransaction().begin();
em.getTransaction().commit();

Query query = em.createNamedQuery("Plant.getPlantById");
...

I don't know what this change exactly does but it works for me :) Maybe someone knows why this solution does work?

PS: I just copied it from another class of mine where I had to add data to the DB and this was the only difference between the both classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM