I am writing an application which is based on spring boot and tries to store and retrieve data from PostGreSQL db in its jsonb column.
while saving the record it works fine but the moment i write basic method to find records in repository interface of it like this:-
public interface AgentProfileRepository extends CrudRepository<AgentProfileOuter,String> {
public AgentProfileOuter findByJdataPcpAgentId(String id);
}
then server starts giving this exception while restarting:-
Caused by: java.lang.IllegalStateException: Illegal attempt to dereference path source [null.jdata] of basic type
at org.hibernate.jpa.criteria.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:98) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.hibernate.jpa.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:191) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:524) ~[spring-data-jpa-1.9.4.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:478) ~[spring-data-jpa-1.9.4.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:300) ~[spring-data-jpa-1.9.4.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:243) ~[spring-data-jpa-1.9.4.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:148) ~[spring-data-jpa-1.9.4.RELEASE.jar:na]
The point to wonder is when I try to find by id which is a normal numeric column in postgres it works fine but not if i try to find by a key inside json.This thing works successfully with MongoDB.
Here are the bean classes written:-
AgentProfileOuter.java
import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Table(name = "Agentbonds")
#Entity
public class AgentProfileOuter {
#GeneratedValue(strategy=GenerationType.AUTO)
#Id
private long id;
#Convert(converter = ConverterAgent.class)
#Column(name="jdata")
private AgentProfile jdata;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public AgentProfile getJdata() {
return jdata;
}
public void setJdata(AgentProfile jdata) {
this.jdata = jdata;
}
}
AgentProfile.java
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;
import org.springframework.data.annotation.Id;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({
"pcpAgentId",
"name",
"bio",
"phone",
"email",
"sms",
"imageUrl"
})
public class AgentProfile {
#JsonProperty("pcpAgentId")
private String pcpAgentId;
/*
public void setAdditionalProperties(Map<String, Object> additionalProperties) {
this.additionalProperties = additionalProperties;
}
*/
#JsonProperty("name")
private String name;
#JsonProperty("bio")
private String bio;
#JsonProperty("phone")
private String phone;
#JsonProperty("email")
private String email;
#JsonProperty("sms")
private String sms;
#JsonProperty("imageUrl")
private String imageUrl;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The pcpAgentId
*/
#JsonProperty("pcpAgentId")
public String getpcpAgentId() {
return pcpAgentId;
}
/**
*
* #param pcpAgentId
* The pcpAgentId
*/
#JsonProperty("pcpAgentId")
public void setAgentId(String pcpAgentId) {
this.pcpAgentId = pcpAgentId;
}
/**
*
* #return
* The name
*/
#JsonProperty("name")
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The bio
*/
#JsonProperty("bio")
public String getBio() {
return bio;
}
/**
*
* #param bio
* The bio
*/
#JsonProperty("bio")
public void setBio(String bio) {
this.bio = bio;
}
/**
*
* #return
* The phone
*/
#JsonProperty("phone")
public String getPhone() {
return phone;
}
/**
*
* #param phone
* The phone
*/
#JsonProperty("phone")
public void setPhone(String phone) {
this.phone = phone;
}
/**
*
* #return
* The email
*/
#JsonProperty("email")
public String getEmail() {
return email;
}
/**
*
* #param email
* The email
*/
#JsonProperty("email")
public void setEmail(String email) {
this.email = email;
}
/**
*
* #return
* The sms
*/
#JsonProperty("sms")
public String getSms() {
return sms;
}
/**
*
* #param sms
* The sms
*/
#JsonProperty("sms")
public void setSms(String sms) {
this.sms = sms;
}
/**
*
* #return
* The imageUrl
*/
#JsonProperty("imageUrl")
public String getImageUrl() {
return imageUrl;
}
/**
*
* #param imageUrl
* The imageUrl
*/
#JsonProperty("imageUrl")
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
Any help on this is greatly appreciated.
I think, it's because how both Mongo and PostGreSQL structure the data. From Mongo's point, AgentProfileOuter is one document saved in JSON format as key:value. Every field in your AgentProfile class is key for Mongo irrespective of the fact it's another/ child object. However, for PostGreSQL whole AgentProfile object is just one column of String blob, since you have not marked this class as #Entity and it does not have a primary id. So, when you try to search something like pcpAgentId=someid, it does not make any sense to PostGreSQL. This is my guess, verify by checking your data structure in PostGreSQL.
Also noticed that CrudRepository<AgentProfileOuter,String> should be like CrudRepository<AgentProfileOuter,long> since AgentProfilOuter class's primary key is long.
Related
I have an application that queries a lot of data and then inserts it into specific tables. Due to the fact that there are many records, the application is taking a long time to complete. The funny thing is that the times it has been executed, it always ends after 1 hour showing SpringApplicationShutdownHook, this It causes not all the records to be processed and many need to be added.
I leave some screenshots of the log , please help.
aplication starts at 16:08:14
shutdown message on log at 17:08:13
#Java8, #Springboot, #Postgree , #Oracle
I tried to review the configuration files, but I only found default hikari configuration with times but they are not 1 hour.
[aplication.properties]
logging.config=classpath:logback.xml
spring.config.location=D:/sise/dev/config.properties
postgre.jpa.show-sql=false
postgre.jpa.hibernate.ddl-auto=update
postgre.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
log of database connection is closing after 1 hour:
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Shutdown initiated...
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-3 - Shutdown completed.
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown initiated...
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown completed.
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2023-01-09 17:08:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
[com.zaxxer.hikari.HikariConfig]
/*
* Copyright (C) 2013, 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.zaxxer.hikari.metrics.MetricsTrackerFactory;
import com.zaxxer.hikari.util.PropertyElf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessControlException;
import java.sql.Connection;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadLocalRandom;
import static com.zaxxer.hikari.util.UtilityElf.getNullIfEmpty;
import static com.zaxxer.hikari.util.UtilityElf.safeIsAssignableFrom;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
#SuppressWarnings({"SameParameterValue"})
public class HikariConfig implements HikariConfigMXBean
{
private static final Logger LOGGER = LoggerFactory.getLogger(HikariConfig.class);
private static final char[] ID_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
private static final long CONNECTION_TIMEOUT = SECONDS.toMillis(30);
private static final long VALIDATION_TIMEOUT = SECONDS.toMillis(5);
private static final long SOFT_TIMEOUT_FLOOR = Long.getLong("com.zaxxer.hikari.timeoutMs.floor", 250L);
private static final long IDLE_TIMEOUT = MINUTES.toMillis(10);
private static final long MAX_LIFETIME = MINUTES.toMillis(30);
private static final long DEFAULT_KEEPALIVE_TIME = 0L;
private static final int DEFAULT_POOL_SIZE = 10;
private static boolean unitTest = false;
// Properties changeable at runtime through the HikariConfigMXBean
//
private volatile String catalog;
private volatile long connectionTimeout;
private volatile long validationTimeout;
private volatile long idleTimeout;
private volatile long leakDetectionThreshold;
private volatile long maxLifetime;
private volatile int maxPoolSize;
private volatile int minIdle;
private volatile String username;
private volatile String password;
// Properties NOT changeable at runtime
//
private long initializationFailTimeout;
private String connectionInitSql;
private String connectionTestQuery;
private String dataSourceClassName;
private String dataSourceJndiName;
private String driverClassName;
private String exceptionOverrideClassName;
private String jdbcUrl;
private String poolName;
private String schema;
private String transactionIsolationName;
private boolean isAutoCommit;
private boolean isReadOnly;
private boolean isIsolateInternalQueries;
private boolean isRegisterMbeans;
private boolean isAllowPoolSuspension;
private DataSource dataSource;
private Properties dataSourceProperties;
private ThreadFactory threadFactory;
private ScheduledExecutorService scheduledExecutor;
private MetricsTrackerFactory metricsTrackerFactory;
private Object metricRegistry;
private Object healthCheckRegistry;
private Properties healthCheckProperties;
private long keepaliveTime;
private volatile boolean sealed;
/**
* Default constructor
*/
public HikariConfig()
{
dataSourceProperties = new Properties();
healthCheckProperties = new Properties();
minIdle = -1;
maxPoolSize = -1;
maxLifetime = MAX_LIFETIME;
connectionTimeout = CONNECTION_TIMEOUT;
validationTimeout = VALIDATION_TIMEOUT;
idleTimeout = IDLE_TIMEOUT;
initializationFailTimeout = 1;
isAutoCommit = true;
keepaliveTime = DEFAULT_KEEPALIVE_TIME;
String systemProp = System.getProperty("hikaricp.configurationFile");
if (systemProp != null) {
loadProperties(systemProp);
}
}
/**
* Construct a HikariConfig from the specified properties object.
*
* #param properties the name of the property file
*/
public HikariConfig(Properties properties)
{
this();
PropertyElf.setTargetFromProperties(this, properties);
}
/**
* Construct a HikariConfig from the specified property file name. <code>propertyFileName</code>
* will first be treated as a path in the file-system, and if that fails the
* Class.getResourceAsStream(propertyFileName) will be tried.
*
* #param propertyFileName the name of the property file
*/
public HikariConfig(String propertyFileName)
{
this();
loadProperties(propertyFileName);
}
// ***********************************************************************
// HikariConfigMXBean methods
// ***********************************************************************
/** {#inheritDoc} */
#Override
public String getCatalog()
{
return catalog;
}
/** {#inheritDoc} */
#Override
public void setCatalog(String catalog)
{
this.catalog = catalog;
}
/** {#inheritDoc} */
#Override
public long getConnectionTimeout()
{
return connectionTimeout;
}
/** {#inheritDoc} */
#Override
public void setConnectionTimeout(long connectionTimeoutMs)
{
if (connectionTimeoutMs == 0) {
this.connectionTimeout = Integer.MAX_VALUE;
}
else if (connectionTimeoutMs < SOFT_TIMEOUT_FLOOR) {
throw new IllegalArgumentException("connectionTimeout cannot be less than " + SOFT_TIMEOUT_FLOOR + "ms");
}
else {
this.connectionTimeout = connectionTimeoutMs;
}
}
/** {#inheritDoc} */
#Override
public long getIdleTimeout()
{
return idleTimeout;
}
/** {#inheritDoc} */
#Override
public void setIdleTimeout(long idleTimeoutMs)
{
if (idleTimeoutMs < 0) {
throw new IllegalArgumentException("idleTimeout cannot be negative");
}
this.idleTimeout = idleTimeoutMs;
}
/** {#inheritDoc} */
#Override
public long getLeakDetectionThreshold()
{
return leakDetectionThreshold;
}
/** {#inheritDoc} */
#Override
public void setLeakDetectionThreshold(long leakDetectionThresholdMs)
{
this.leakDetectionThreshold = leakDetectionThresholdMs;
}
/** {#inheritDoc} */
#Override
public long getMaxLifetime()
{
return maxLifetime;
}
/** {#inheritDoc} */
#Override
public void setMaxLifetime(long maxLifetimeMs)
{
this.maxLifetime = maxLifetimeMs;
}
/** {#inheritDoc} */
#Override
public int getMaximumPoolSize()
{
return maxPoolSize;
}
/** {#inheritDoc} */
#Override
public void setMaximumPoolSize(int maxPoolSize)
{
if (maxPoolSize < 1) {
throw new IllegalArgumentException("maxPoolSize cannot be less than 1");
}
this.maxPoolSize = maxPoolSize;
}
/** {#inheritDoc} */
#Override
public int getMinimumIdle()
{
return minIdle;
}
/** {#inheritDoc} */
#Override
public void setMinimumIdle(int minIdle)
{
if (minIdle < 0) {
throw new IllegalArgumentException("minimumIdle cannot be negative");
}
this.minIdle = minIdle;
}
/**
* Get the default password to use for DataSource.getConnection(username, password) calls.
* #return the password
*/
public String getPassword()
{
return password;
}
/**
* Set the default password to use for DataSource.getConnection(username, password) calls.
* #param password the password
*/
#Override
public void setPassword(String password)
{
this.password = password;
}
/**
* Get the default username used for DataSource.getConnection(username, password) calls.
*
* #return the username
*/
public String getUsername()
{
return username;
}
/**
* Set the default username used for DataSource.getConnection(username, password) calls.
*
* #param username the username
*/
#Override
public void setUsername(String username)
{
this.username = username;
}
/** {#inheritDoc} */
#Override
public long getValidationTimeout()
{
return validationTimeout;
}
/** {#inheritDoc} */
#Override
public void setValidationTimeout(long validationTimeoutMs)
{
if (validationTimeoutMs < SOFT_TIMEOUT_FLOOR) {
throw new IllegalArgumentException("validationTimeout cannot be less than " + SOFT_TIMEOUT_FLOOR + "ms");
}
this.validationTimeout = validationTimeoutMs;
}
I'm having troubles implementing JPA methods in my WebApp built in Java ee 7, its returned me "EJBException : Transaction aborted" , but the parameters "ID" and "Description" had send correctly.
package entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author Fede-Frost
*/
#Entity
#Table(name = "especialidad")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Especialidad.findAll", query = "SELECT e FROM Especialidad e")
, #NamedQuery(name = "Especialidad.findById", query = "SELECT e FROM Especialidad e WHERE e.id = :id")
, #NamedQuery(name = "Especialidad.findByDesc", query = "SELECT e FROM Especialidad e WHERE e.desc = :desc")})
public class Especialidad implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Integer id;
#Size(max = 45)
#Column(name = "desc")
private String desc;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "especialidad")
private List<Medico> medicoList;
public Especialidad() {
}
public Especialidad(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
#XmlTransient
public List<Medico> getMedicoList() {
return medicoList;
}
public void setMedicoList(List<Medico> medicoList) {
this.medicoList = medicoList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Especialidad)) {
return false;
}
Especialidad other = (Especialidad) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "MyHospital.Especialidad[ id=" + id + " ]";
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package model;
import entities.Estudiolab;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
*
* #author Fede-Frost
*/
#Stateless
public class EstudiolabFacade extends AbstractFacade<Estudiolab> implements EstudiolabFacadeLocal {
#PersistenceContext(unitName = "MyHospital-ejbPU")
private EntityManager em;
#Override
protected EntityManager getEntityManager() {
return em;
}
public EstudiolabFacade() {
super(Estudiolab.class);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package model;
import entities.Especialidad;
import java.util.List;
import javax.ejb.Local;
/**
*
* #author Fede-Frost
*/
#Local
public interface EspecialidadFacadeLocal {
void create(Especialidad especialidad);
void edit(Especialidad especialidad);
void remove(Especialidad especialidad);
Especialidad find(Object id);
List<Especialidad> findAll();
List<Especialidad> findRange(int[] range);
int count();
}
And here it's the big deal, on the controller
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package controller;
import entities.Especialidad;
import javax.inject.Named;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import model.EspecialidadFacadeLocal;
/**
*
* #author Fede-Frost
*/
#ViewScoped
#Named(value = "mediCon")
public class mediCon implements Serializable {
#EJB
private EspecialidadFacadeLocal especFac;
#Inject
private Especialidad espec;
/**
* Creates a new instance of MediCon
* #return
*/
public void addSpec() {
try {
especFac.create(espec);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Exito", "Se registro correctamente"));
} catch (EJBException e) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Aviso", e.toString() ));
}
}
public Especialidad getEspec() {
return espec;
}
public void setEspec(Especialidad espec) {
this.espec = espec;
}
}
As I said, JSF sent me the correct parameters which I tested with FacesContext.addMessage, but I don't know why it doesn't work, thanks in advance.
If a SystemException(A system exception must be a subclass
of a RuntimeException or java.rmi.RemoteException) is thrown, the current transaction will be rollbacked
For more information about the Exception types in EJB, you could have a look at this link.
but the query it's from JPA standard created on especialidadFacade
with especialidaEntity
please have a look at JPA: Weird error when I try to persist an object
in your case, "desc" is a reserved keyword
i m a total newbie to JPQL ,so i m working on a Spring Boot app and i have this SQL query part :
select TOP 10 RFC_NUMBER, RECIPIENT_ID from [50004].SD_REQUEST S
INNER JOIN [50004].AM_EMPLOYEE E
--ON S.RECIPIENT_ID = E.EMPLOYEE_ID
WHERE E.AVAILABLE_FIELD_5 ='j.doe'
AND SD_REQUEST.STATUS_ID NOT IN (8,6,18,7,24)
AND SD_REQUEST.RFC_NUMBER like 'I%'
to JPQL.
i tried doing a #Query like this :
#Query("select x from Incident x Left join x.recipient recip where recip.login=:login and (x.rfcnumber like :I_% or :rfcnumber = null )"
+ " and x.status NOT IN (8,6,18,7,24)")
but it only returns ALL the rfcnumber of the that employee , i want it to extract only the rfc number starting with letter I ,
i tried doing CONCAT from searching around in then web, same thing.
i m new to this so i figure it'll be something much simpler , i m thinking it's just syntax problem .
Thanks a bunch.
Edit (adding models):
import java.io.Serializable;
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="SD_REQUEST")
public class Incident implements Serializable {
private static final long serialVersionUID = -8235081865121541091L;
#Id
#Column(name="REQUEST_ID")
private Integer inid;
#ManyToOne
#JoinColumn(name = "SUBMITTED_BY")
private Employee sender;
#Column(name="RFC_NUMBER")
private String rfcnumber;
#Column(name="CREATION_DATE_UT")
private Date date;
#Column(name="DESCRIPTION")
private String description;
#Column(name="COMMENT")
private String comment;
#Column(name="STATUS_ID")
private Integer status;
#ManyToOne
#JoinColumn(name = "RECIPIENT_ID")
private Employee recipient;
public Incident()
{
}
public Incident(int inid,String rfcnumber,Date date,String description,String comment,Integer status)
{
this.inid=inid;
this.rfcnumber= rfcnumber;
this.date=date;
this.description=description;
this.comment=comment;
this.status=status;
}
public int getInid() {
return inid;
}
public void setInid(int inid) {
this.inid = inid;
}
public String getRfcnumber() {
return rfcnumber;
}
public void setRfcnumber(String rfcnumber) {
this.rfcnumber = rfcnumber;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Employee getSender() {
return sender;
}
public void setSender(Employee sender) {
this.sender = sender;
}
public Employee getRecipient() {
return recipient;
}
public void setRecipient(Employee recipient) {
this.recipient = recipient;
}
public void setInid(Integer inid) {
this.inid = inid;
}
}
And here's the model for Employee :
import javax.persistence.*;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
#Entity
#JsonDeserialize(as =Employee.class)
#Table(name = "AM_EMPLOYEE")
public class Employee implements Serializable {
private static final long serialVersionUID = 5071617893593927440L;
#Id
#Column(name = "EMPLOYEE_ID" )
private Integer id;
#Column(name = "LAST_NAME")
private String lastName;
#Column(name = "AVAILABLE_FIELD_5")
private String login;
#OneToMany(mappedBy="sender")
#JsonIgnore
private List<Incident> myCreatedIncidents;
#OneToMany(mappedBy="recipient")
#JsonIgnore
private List<Incident> myOtherIncidents;
#Column(name = "PASSWD")
private String password;
public Employee() {
//super();
}
public Employee (String login,String password)
{
}
public Employee(Integer id, String lastName,String login, String password) {
this.id = id;
this.lastName = lastName;
this.login = login;
this.password = password;
}
/**
* #return the id
*/
public Integer getId() {
return id;
}
/**
* #param id
* the id to set
*/
public void setId(Integer id) {
this.id = id;
}
/**
* #return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* #param lastName
* the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* #return the login
*/
public String getLogin() {
return login;
}
/**
* #param login
* the login to set
*/
public void setLogin(String login) {
this.login = login;
}
/**
* #return the password
*/
public String getPassword() {
return password;
}
/**
* #param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
public List<Incident> getMyCreatedIncidents() {
return myCreatedIncidents;
}
public void setMyCreatedIncidents(List<Incident> myCreatedIncidents) {
this.myCreatedIncidents = myCreatedIncidents;
}
public List<Incident> getMyOtherIncidents() {
return myOtherIncidents;
}
public void setMyOtherIncidents(List<Incident> myOtherIncidents) {
this.myOtherIncidents = myOtherIncidents;
}
}
Hard-coded characters
I think you should use the same as in SQL:
like 'I%'
Specifically, according to the article # http://www.objectdb.com/java/jpa/query/jpql/string#LIKE_-_String_Pattern_Matching_with_Wildcards_ :
The percent character (%) - which matches zero or more of any character.
Blockquote
So try the following:
#Query("select x from Incident x Left join x.recipient recip where recip.login=:login and (x.rfcnumber like 'I%' or :rfcnumber = null )"
+ " and x.status NOT IN (8,6,18,7,24)"
)
Parameters
See the solutions # Parameter in like clause JPQL if you are using a parameter.
Examples:
LIKE :code%
Also other examples are included in the stackoverflow question.
#Query("select x from Incident x where x.recipient.login=:login and (x.rfcnumber like I% or x.rfcnumber = null )"
+ " and x.status NOT IN (8,6,18,7,24))"
try this query
I'm representing Appointments in an entity bean which have a startTime and endTime of type Calendar. This is stored using JPA as TIMESTAMP. If I edit the Appointment object's start / end time it updates on the object itself during the session but it's not updated within the database itself. Other elements such as the Appointment's description successfully update in the database.. It's only he start and end time which are not.
Entity class (this is indirectly updated in the database with EntityManager.merge():
package mcknighte.entity;
import java.io.Serializable;
import java.util.Calendar;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import static javax.persistence.TemporalType.TIMESTAMP;
import javax.validation.constraints.NotNull;
import mcknighte.common.Convertable;
/**
* Appointment entity class, to represent an Appointment within the database
* and throughout the application
*
* #author Edward McKnight (UP608985)
* #see Client
* #see AppointmentFacade
* #see AppointmentService
* #see AppointmentController
* #since 2017
* #version 1.0
*/
#Entity
public class Appointment implements Serializable, Convertable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Temporal(TIMESTAMP)
private Calendar startTime;
#NotNull
#Temporal(TIMESTAMP)
private Calendar endTime;
#NotNull
private String description;
#NotNull
#ManyToOne(targetEntity = Client.class)
private Client creator;
#NotNull
#OneToMany(targetEntity = Client.class)
private List<Client> attendees;
/**
* Constructor
*/
public Appointment() {
this.startTime = Calendar.getInstance();
this.endTime = Calendar.getInstance();
}
/**
* Get the attendees for the appointment
*
* #return a list of attendees for the appointment
*/
public List<Client> getAttendees() {
return attendees;
}
/**
* Set the attendees for the appointment
*
* #param attendees a list of attendees for the appointment
*/
public void setAttendees(List<Client> attendees) {
this.attendees = attendees;
}
/**
* Get the creator of the appointment
*
* #return the creator of the appointment
*/
public Client getCreator() {
return creator;
}
/**
* Set the creator of the appointment
*
* #param creator the creator of the appointment
*/
public void setCreator(Client creator) {
this.creator = creator;
}
/**
* Get the description for the appointment
*
* #return the description for the appointment
*/
public String getDescription() {
return description;
}
/**
* Set the description for the appointment
*
* #param description the description for the appointment
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Get the end time of the appointment
*
* #return the end time of the appointment
*/
public Calendar getEndTime() {
return endTime;
}
/**
* Set the end time of the appointment
*
* #param end the end time of the appointment
*/
public void setEndTime(Calendar end) {
this.endTime = end;
}
/**
* Get the start time of the appointment
*
* #return the start time of the appointment
*/
public Calendar getStartTime() {
return startTime;
}
/**
* Set the start time of the appointment
*
* #param start the start time of the appointment
*/
public void setStartTime(Calendar start) {
this.startTime = start;
}
/**
* Get the ID for the appointment
*
* #return the ID for the appointment
*/
#Override
public Long getId() {
return id;
}
/**
* Set the ID for the appointment
*
* #param id the ID for the appointment
*/
public void setId(Long id) {
this.id = id;
}
/**
* Hash code
*
* #return int
*/
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
/**
* Equals
*
* #param object the object to compare to
* #return whether or not this equals the object being compared to
*/
#Override
public boolean equals(Object object) {
if (!(object instanceof Appointment)) {
return false;
}
Appointment other = (Appointment) object;
return !((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)));
}
/**
* Represent this object as a string
*
* #return a string representation of this object
*/
#Override
public String toString() {
return "mcknighte.entity.Appointment[ id=" + id + " ]";
}
}
The issue has been resolved after finding another StackOverflow question and reading the Oracle documentation.
All that needed to be done was to add an #Mutable annotation to each of the Calendar properties, as Date and Calendar are immutable by default.
I need to manage 2 databases in my application. For it, i have developed a sample application using EclipseLink Composite Persistence Unit feature.
However during my tests i notice a strange behaviour:
- basics jpa operations (persist, merge, remove or JPQL code) work perfectly
- but when i use the criteria api, EclipseLink return me the following error:
java.lang.IllegalArgumentException: No [EntityType] was found for the key class [com.example.common.entity.ThirdParty] in the Metamodel - please verify that the [Entity] class was referenced in persistence.xml using a specific <class>com.example.common.entity.ThirdParty</class> property or a global <exclude-unlisted-classes>false</exclude-unlisted-classes> element.
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.entityEmbeddableManagedTypeNotFound(MetamodelImpl.java:177)
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.entity(MetamodelImpl.java:198)
at org.eclipse.persistence.internal.jpa.querydef.CommonAbstractCriteriaImpl.internalFrom(CommonAbstractCriteriaImpl.java:113)
at org.eclipse.persistence.internal.jpa.querydef.AbstractQueryImpl.from(AbstractQueryImpl.java:246)
at com.example.data.dao.ClientTest.testSelectByCriteria(ClientTest.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
This is the code of my sample (basically 2 entities and one Junit test)
My composite persistence.xml:
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<persistence 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"
version="2.0">
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jar-file>file://D:\projects\prj-archetypes\trunk\workspace\sample\sample-common\target\sample-common-0.0.1-SNAPSHOT.jar</jar-file>
<properties>
<property name="eclipselink.composite-unit" value="true" />
</properties>
</persistence-unit>
My member persistence.xml, located on sample-common-0.0.1-SNAPSHOT.jar:
<persistence 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"
version="2.0">
<persistence-unit name="memberPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.commons.entity.AbstractEntity</class>
<class>com.example.common.entity.ThirdParty</class>
<class>com.example.common.entity.Address</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/H2default" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<!-- <property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.H2Platform"
/>
-->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINEST" />
</properties>
</persistence-unit>
My entities, also on sample-common-0.0.1-SNAPSHOT.jar:
ThirdParty:
package com.example.common.entity;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.Generated;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import com.example.common.Gender;
import com.commons.entity.AbstractEntity;
/**
* ThirdParty entity.
*/
#Entity
public class ThirdParty
extends AbstractEntity
{
/**
* Constructor.
*/
public ThirdParty()
{
super();
}
/**
* Serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* firstname.
*/
#Column(name = "FIRST_NAME", nullable = false)
#NotNull
private String firstName;
/**
* last name.
*/
#Column(name = "LAST_NAME", nullable = false)
#NotNull
#Size(max = 30)
private String lastName;
/**
* Birth date.
*/
#Column(name = "BIRTH_DATE", nullable = false)
#NotNull
#Temporal(TemporalType.TIMESTAMP)
private Date birthdate;
/**
* last name.
*/
#Column(name = "AGE", nullable = false, precision = 0)
#NotNull
private Integer age;
/**
* ThirdParty civility.
*/
#Column(name = "CIVILITY", nullable = false)
#NotNull
#Enumerated(EnumType.STRING)
private Gender civility;
/**
* addressList.
*/
#OneToMany(mappedBy = "thirdParty", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
private List<Address> addressList = new ArrayList<Address>();
/**
* Get firstName.
* #return String
*/
public String getFirstName()
{
return firstName;
}
/**
* Set firstName.
* #param firstName String
*/
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
/**
* Get lastName.
* #return String
*/
public String getLastName()
{
return lastName;
}
/**
* Set lastName.
* #param lastName String
*/
public void setLastName(String lastName)
{
this.lastName = lastName;
}
/**
* Get birthdate.
* #return Date
*/
public Date getBirthdate()
{
Date tempDate = birthdate;
if (tempDate != null)
{
tempDate = (Date) birthdate.clone();
}
return tempDate;
}
/**
* Set birthdate.
* #param birthdate Date
*/
public void setBirthdate(Date birthdate)
{
if (birthdate == null)
{
this.birthdate = null;
}
else
{
this.birthdate = (Date) birthdate.clone();
}
}
/**
* Get age.
* #return Integer
*/
public Integer getAge()
{
return age;
}
/**
* Set age.
* #param age Integer
*/
public void setAge(Integer age)
{
this.age = age;
}
/**
* Get civility.
* #return Gender
*/
public Gender getCivility()
{
return civility;
}
/**
* Set civility.
* #param civility Gender
*/
public void setCivility(Gender civility)
{
this.civility = civility;
}
/**
* Get addressList.
* #return Address
*/
public List<Address> getAddressList()
{
return addressList;
}
/**
* Set addressList.
* #param addressList Address
*/
public void setAddressList(List<Address> addressList)
{
this.addressList = addressList;
}
/**
* Add addressList.
* #param addressList Address
*/
public void addAddressList(Address addressList)
{
this.addressList.add(addressList);
}
}
Address entity:
package com.example.common.entity;
import javax.annotation.Generated;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.commons.entity.AbstractEntity;
/**
* Address entity.
*/
#Entity
public class Address
extends AbstractEntity
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* street.
*/
#Column(name = "STREET")
private String street;
/**
* City.
*/
#Column(name = "CITY")
private String city;
/**
* Zipcode.
*/
#Column(name = "ZIPCODE", precision = 0)
private Integer zipcode;
/**
* Third Party.
*/
#ManyToOne
private ThirdParty thirdParty;
/**
* Get street.
* #return String
*/
public String getStreet()
{
return street;
}
/**
* Set street.
* #param street String
*/
public void setStreet(String street)
{
this.street = street;
}
/**
* Get city.
* #return String
*/
public String getCity()
{
return city;
}
/**
* Set city.
* #param city String
*/
public void setCity(String city)
{
this.city = city;
}
/**
* Get zipcode.
* #return Integer
*/
public Integer getZipcode()
{
return zipcode;
}
/**
* Set zipcode.
* #param zipcode Integer
*/
public void setZipcode(Integer zipcode)
{
this.zipcode = zipcode;
}
/**
* Get thirdParty.
* #return ThirdParty
*/
public ThirdParty getThirdParty()
{
return thirdParty;
}
/**
* Set thirdParty.
* #param ThirdParty
*/
public void setThirdParty(ThirdParty thirdParty)
{
this.thirdParty = thirdParty;
}
}
And finally the JUnit test class:
package com.example.data.dao;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.sopra.banking.example.common.Gender;
import com.sopra.banking.example.common.entity.Address;
import com.sopra.banking.example.common.entity.ThirdParty;
import junit.framework.Assert;
public class ClientTest
{
private static EntityManagerFactory emf;
private static EntityManager em;
private static EntityTransaction tx;
#BeforeClass
public static void initEntityManager()
throws Exception
{
emf = Persistence.createEntityManagerFactory("testPersistenceUnit");
em = emf.createEntityManager();
}
#AfterClass
public static void closeEntityManager()
throws SQLException
{
em.close();
emf.close();
}
#Before
public void initTransaction()
{
tx = em.getTransaction();
}
#Test
public void testInsert()
throws ParseException
{
// Create an instance of ThirdParty
ThirdParty thirdParty = new ThirdParty();
// Create an instance of Address
Address address = new Address();
// set address
address.setCity("Annecy");
address.setStreet("street");
address.setZipcode(74000);
ArrayList<Address> addresses = new ArrayList<Address>();
addresses.add(address);
// set client
thirdParty.setCivility(Gender.MISTER);
thirdParty.setAge(17);
thirdParty.setBirthdate(new SimpleDateFormat("yyyy-MM-dd").parse("2011-01-01"));
thirdParty.setFirstName("firstName");
thirdParty.setLastName("lastName");
thirdParty.setAddressList(addresses);
address.setThirdParty(thirdParty);
// Persists the client in DB
tx.begin();
em.persist(thirdParty);
tx.commit();
Assert.assertNotNull("ID should not be null", thirdParty.getId());
}
#Test
public void testSelectById()
throws ParseException
{
ThirdParty thirdParty = em.find(ThirdParty.class, 1);
Assert.assertEquals(true, true);
}
#Test
public void testSelectAll()
throws ParseException
{
Query query = em.createQuery("SELECT t FROM ThirdParty t");
List<ThirdParty> thirdParties = query.getResultList();
Assert.assertEquals(true, true);
}
#Test
public void testSelectByCriteria()
{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<ThirdParty> criteriaQuery = qb.createQuery(ThirdParty.class);
Root<ThirdParty> thRoot = criteriaQuery.from(ThirdParty.class);
criteriaQuery.select(thRoot);
List<ThirdParty> thirdPartyList = em.createQuery(criteriaQuery).getResultList();
Assert.assertEquals(true, true);
}
}
testInsert, testSelectAll and testSelectById work well but testSelectByCriteria crashes with the error trace on the beginning of my post.
During debug i notice that typeMap is empty on class:
org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl on method entityEmbeddableManagedTypeNotFound
private void entityEmbeddableManagedTypeNotFound(Map typeMap, Object aType, Class clazz, String metamodelType, String metamodelTypeName) {
// 338837: verify that the collection is not empty - this would mean entities did not make it into the search path
if(typeMap.isEmpty()) {
AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.METAMODEL, "metamodel_type_collection_empty_during_lookup", clazz, metamodelTypeName);
}
// A null type will mean either the metamodel type does not exist because it was not found/processed, or the clazz is not part of the model
if(null == clazz) {
throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
"metamodel_class_null_type_instance_for_null_key",
new Object[] { metamodelTypeName, metamodelType}));
} else {
if(null == aType) {
throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
"metamodel_class_null_type_instance",
new Object[] { clazz.getCanonicalName(), metamodelTypeName, metamodelType}));
} else {
Has anyone ever encountered this problem, it seems managed entites are not visible because the map
Map<String, EntityTypeImpl<?>> entities
is empty.
I try to generate metamodel classes following this procedure jpa-metamodels-with-maven but call using Criteria still failing.
You bind an entity manager to testPersistenceUnit Persistence.createEntityManagerFactory("testPersistenceUnit"), but you also need an dedicated (individual!) entity manger for memberPU.
At the moment, you eventually try to fetch a ThirdParty via the testPersistenceUnit which is not possible, because you exclude-unlisted-classes'ed it.
Introduce a second entity manager, grab your third party entity using the second entity manager. Do not try to fetch a third party using the first manager.