try {
LOG.debug("Entering readDb at {}",
System.currentTimeMillis());
Session session =
transactionManager.getSessionFactory().getCurrentSession();
Query query = null;
ReturnTrackerEntity rtEntity = null;
List<ReturnTrackerEntity> rtEntityList = null;
query = session.createQuery("SELECT r FROM org.hx.api.returns.model.entity.ReturnTrackerEntity r WHERE r.hxinRefId = :hxinRefId AND r.rtnTyp = :rtnTyp AND r.rtnPrd = :rtnPrd");
if (query != null) {
query.setString("hxinRefId", key.gethxinRefId());
query.setString("rtnTyp", key.getRtnTyp());
query.setString("rtnPrd", key.getRtnPeriod());
LOG.debug("Query Parameters are {} {} {}", key.gethxinRefId(), key.getRtnTyp(), key.getRtnPeriod());
rtEntityList = query.list();
if(rtEntityList != null && !rtEntityList.isEmpty()) {
rtEntity = (ReturnTrackerEntity) query.list().get(0);
}
LOG.debug("Data from readDb at :{}", rtEntity);
}
return rtEntity;
When executing the above method I'm getting following exception;
java.lang.IllegalArgumentException: Parameter hxinRefId does not exist as a named parameter in [SELECT r FROM org.hx.api.returns.model.entity.ReturnTrackerEntity r WHERE r.hxinRefId = :hxinRefId AND r.rtnTyp = :rtnTyp AND r.rtnPrd = :rtnPrd]
I have tried using setParameters still it shows error:
org.hibernate.QueryParameterException: could not locate named parameter [hxinRefId]
This is the enitity class followed by getter setter:
#Entity
#Table(name = "RTN_TRACKER")
#NamedQuery(
name = "ReturnTrackerEntity.getReturnTracker",
query = "SELECT r FROM org.hx.api.returns.model.entity.ReturnTrackerEntity r WHERE r.hxinRefId = :hxinRefId AND r.rtnTyp = :rtnTyp AND r.rtnPrd = :rtnPrd")
public class ReturnTrackerEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private int id;
#Column(name = "HXIN_REF_ID")
private String hxinRefId;
#Column(name = "RTN_TYP")
private String rtnTyp;
#Column(name = "RTN_PRD")
private String rtnPrd;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "LATEST_SAVE_END")
private Date lastSaveEndTmpStmp;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "LATEST_START")
private Date lastStartTmpStmp;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "INSERT_TMSTMP")
private Date insertTmpStmp;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "UPDATE_TMSTMP")
private Date updateTmpStmp;
#Column(name = "STATE_CD")
private String stateCd;
Also I have tried passing only the Entity class name without whole location still getting error.
please help with this stuck for so long in this.
Related
I'm trying to call a procedure function in DB and to mapped the Hierarchy answer to entity class using hibernate.The entities that I wrote suppose to represent the result structure that is returned from a ref cursor function.
The result of the function has a property which is a list of objects and inside that object there is also a property that is also a list of another objects.
On application startup I get the MappingException as I wrote in the title above.
I tried to add the annotation #OneToMany but it is not working because it is not looking at tables in DB.
Again, the entities represent the function result and not select from table tables.
Someone has any idea of any annotation that could prevent from this exeception to araise in the application startup?
My Entities:
Main Entity that call to procedure function (rc):
#NamedNativeQuery(name = "GetDeliveryOptionsRC.runFunction",
query = "{ ? = call fn_get_delivery_options_rc_dev(:i_account_number,:i_work_order_number,:i_task_id,:i_task_type,:i_content_type_code,:i_sap_operator_code)}", resultClass = GetDeliveryOptionsRC.class,
hints = {#QueryHint(name = "org.hibernate.callable", value = "true")})
#Entity
#XmlRootElement(name = "GetDeliveryOptionsRC")
public class GetDeliveryOptionsRC implements Serializable {
#Id
private Long rownum;
#Column(name = "ACCOUNT_NUMBER")private Long accountNumber;
#Column(name = "TASK_TYPE")private Long taskType;
#Column(name = "CONTENT_TYPE")private String contentType;
#Column(name = "CONTENT_TYPE_CODE")private Long contentTypeCode;
#Column(name = "MESSAGE_CODE")private Long messageCode;
#Column(name = "MESSAGE_ERROR_CODE")private Long messageErrorCode;
#Column(name = "MESSAGE_ERROR_DESCR")private String messageErrorDescr;
#Column(name = "DELIVERY_OPTIONS")private List<DeliveryOptionsRC> deliveryOptions;
//getters & setters
}
Delivery Options Entity:
#Entity
#XmlRootElement(name = "DeliveryOptions")
public class DeliveryOptionsRC implements Serializable {
#Id
#Column(name = "DELIVERY_TYPE") private String deliveryType;
#Column(name = "DELIVERY_DESCR") private String deliveryDescr;
#Column(name = "PRICE") private Double price;
#Column(name = "EXISTS_FLAG") private String existFlag;
#Column(name = "IS_VALID") private String isValid;
#Column(name = "IS_SAP_ORDER") private String isSapOrder;
#Column(name = "IS_OTHER_ADDRESS") private String isOtherAddress;
#Column(name = "IS_SCHEDULE_NEEDED") private String isScheduledNeeded;
#Column(name = "PICKUP_SOURCE") private String pickupSource;
#OneToMany(targetEntity=ChargeJobs.class, mappedBy="deliveryOptionsRC", fetch=FetchType.EAGER)
#Column(name = "CHARGE_JOBES") private List<ChargeJobs> chargeJobs;
//getters & setters
}
Charge Jobs Entity:
#Entity
#XmlRootElement(name = "ChargeJobs")
public class ChargeJobs implements Serializable {
#Column(name = "JOB_OFFER_ID") private Long jobOfferId;
#Id
#Column(name = "JOB_CODE") private String jobCode;
#Column(name = "PRICE") private Double price;
#Column(name = "QUANTITY") private Long quantity;
//getters & setters
}
The RC function:
CREATE OR REPLACE FUNCTION YES_SIMPLE.fn_get_delivery_options_rc_dev (i_account_number NUMBER,
i_work_order_number NUMBER ,
i_task_id NUMBER ,
i_task_type NUMBER,
i_content_type_code NUMBER,
i_sap_operator_code NUMBER
)
RETURN sys_refcursor
is
out_ref sys_refcursor ;
ret tr.delivery_options_list_t;
xml sys.xmltype;
begin
ret:= TR.fn_get_delivery_options (p_account_number => i_account_number,
p_work_order_number =>i_work_order_number,
p_task_id =>i_task_id,
p_task_type =>i_task_type,
p_content_type_code =>i_content_type_code,
p_sap_operator_code => i_sap_operator_code) ;
open out_ref for
select ret.Account_number Account_number
,ret.Task_Type Task_Type,
ret.content_type content_type,
ret.content_type_code content_type_code,
ret.message_code message_code,
ret.message_error_code message_error_code,
ret.message_error_descr message_error_descr
,cursor(select DELIVERY_TYPE ,
DELIVERY_DESCR ,
PRICE ,
EXISTS_FLAG ,
IS_VALID ,
IS_SAP_ORDER ,
IS_OTHER_ADRESS ,
IS_SCHEDULE_NEEDED ,
PICKUP_SOURCE,
cursor(select * from(select * from(select * from table(select ret.delivery_options from dual) ))) charge_jobs
from table(select ret.delivery_options from dual) ) delivery_options
from dual;
return out_ref;
end;
Getting the following result:
ROWNUM 1
ACCOUNT_NUMBER 13
TASK_TYPE 1
CONTENT_TYPE OTT
CONTENT_TYPE_CODE 2
MESSAGE_CODE 98
MESSAGE_ERROR_CODE 98
MESSAGE_ERROR_DESCR
DELIVERY_OPTIONS <Cursor>
DELIVERY_TYPE T
DELIVERY_DESCR Tech
PRICE 0
EXISTS_FLAG N
IS_VALID Y
IS_SAP_ORDER N
IS_OTHER_ADRESS N
IS_SCHEDULE_NEEDED Y
PICKUP_SOURCE
CHARGE_JOBS <Cursor>
JOB_OFFER_ID 900310
JOB_CODE D80
PRICE 0
QUANTITY 1
trying to run a native query however I'm getting The column name sb_modelid is not valid. when attempting to map the return object to my model object in java? I have verified all the column names are correct.
1) Why is it referring to my column name as sb_modelid and not sbModelID?
2) Why is not being mapped to my POJO correctly?
Thanks!
Model Object:
package com.dish.wfm.linkingTickets.model.repository;
public class Model {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "sbModelID")
private Long sbModelId;
#Column(name = "modelID")
private String modelID;
#Column(name = "serialNumber")
private String serialNumber;
#Column(name = "serviceContractNumber")
private String serviceContractNumber;
}
Repo:
#Repository
public interface SBModelRepo extends JpaRepository<Model, Long> {
#Query(value = "select m.sbModelID, m.modelID, m.serialNumber, m.serviceContractNumber from sb.Model m where m.modelID = ?1 and m.serialNumber = ?2", nativeQuery = true)
Model findTopByModelIDAndSerialNumber(String modelID, String serialNumber);
}
I'm trying to do a select using a join in CriteriaBuilder, but I'm getting this error in Eclipse. How can I fix it?
Hibernate version: hibernate-jpa-2.0-api<br />
Java Version: 1.8
fonte cannot be solved or is not a field
NotificacaoDao.java
#Stateless
public class NotificacaoDao {
#PersistenceContext(unitName = "PostgreSQLDS")
private EntityManager em;
#EJB
private NotificacaoDao NotificacaoDao;
public List<Notificacao> getResultList(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) throws ApplicationException{
try {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Notificacao> cq = cb.createQuery(Notificacao.class);
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
cq.where(NotificacaoDao.getFilterCondition(cb, myObj, filters));
Predicate filterCondition = NotificacaoDao.getFilterCondition(cb, myObj, filters);
filterCondition = cb.and(filterCondition, cb.equal(myObj.get("excluido"), "N"));
cq.where(filterCondition);
if (sortField != null) {
if (sortOrder == SortOrder.ASCENDING) {
cq.orderBy(cb.asc(myObj.get(sortField)));
} else if (sortOrder == SortOrder.DESCENDING) {
cq.orderBy(cb.desc(myObj.get(sortField)));
}
}
return em.createQuery(cq).setFirstResult(first).setMaxResults(pageSize).getResultList();
} catch(Exception e) {
throw new ApplicationException("myException", e);
}
}
Notificacao.java
#Entity
#Table(name = "tb_notificacao", schema = "indicadores")
#NamedQuery(name = "Notificacao.findAll", query = "SELECT n FROM Notificacao n")
#FilterDef(name="notificacaoNaoExcluido", defaultCondition="excluido = 'N'")
public class Notificacao implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "tb_notificacao_codnotificacao_seq", sequenceName = "TB_NOTIFICACAO_CODNOTIFICACAO_SEQ", schema = "indicadores", allocationSize = 1)
#GeneratedValue(generator = "tb_notificacao_codnotificacao_seq")
#Column(name = "codnotificacao", nullable = false)
private Integer codnotificacao;
private String descricao;
private String excluido;
private String nome;
// bi-directional many-to-one association to CargaNotificacao
#OneToMany(mappedBy = "notificacao")
private List<CargaNotificacao> cargaNotificacoes;
// bi-directional many-to-one association to Fonte
#Inject
#ManyToOne
#JoinColumn(name = "codfonte")
private Fonte fonte;
// bi-directional many-to-one association to UsuarioNotificacao
#OneToMany(mappedBy = "notificacao")
#Filter(name="usuarioNaoExcluido", condition="excluido = 'N'")
private List<UsuarioNotificacao> usuarioNotificacoes;
public Notificacao() {
}
// getters and setters
}
Fonte.java
#Entity
#Table(name = "tb_fonte", schema = "indicadores")
#NamedQuery(name = "Fonte.findAll", query = "SELECT f FROM Fonte f")
public class Fonte implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "tb_fonte_codfonte_seq", sequenceName = "TB_FONTE_CODFONTE_SEQ", schema = "indicadores", allocationSize = 1)
#GeneratedValue(generator = "tb_fonte_codfonte_seq")
#Column(name = "codfonte", nullable = false)
private Integer codfonte;
private String nome;
// bi-directional many-to-one association to Indicador
#OneToMany(mappedBy = "fonte")
#Filter(name="indicadorNaoExcluido", condition="excluido = 'N'")
private List<Indicador> indicadores;
// bi-directional many-to-one association to Notificacao
#OneToMany(mappedBy = "fonte")
#Filter(name="notificacaoNaoExcluido", condition="excluido = 'N'")
private List<Notificacao> notificacoes;
public Fonte() {
}
// getters and setters
}
Well, on Metamodels there are basically three approaches to use:
Using IDE based metamodel generation tools
Using Static Canonical Metamodel Classes
Using em.getMetamodel() API i.e. the one you are using.
The solution I am proposing for you to use which is closer to what you were doing is on Point 3.
Point 3 Solution :
Replace the below code :
Metamodel m = em.getMetamodel();
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(Notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(Notificacao_.fonte); // HERE I'M GETTING THE ERROR
With new code :
Metamodel m = em.getMetamodel();
EntityType<Notificacao> notificacao_ = m.entity(Notificacao.class);
Root<Notificacao> myObj = cq.from(notificacao_);
Join<Notificacao, Fonte> fontes = myObj.join(notificacao_.getSingularAttribute("fonte",Fonte.class));
Points 1 & 2 Solutions
Please note the Notificacao_ must be a class either static or generated and must never be an instance of em.getMetamodel(). Also note in your case before Notificacao_ was a variable instead of a class as shown:
EntityType<Notificacao> Notificacao_ = m.entity(Notificacao.class);
If you need more info, let me know please.
We're making get requests through a controller. The model contains transient fields that are set in the controller. Only int fields that are not null or >0 are being returned by the controller. How can I allow a transient field to return a 0 value, as this is meaningful. In this case the transient fields are 'sentenceStart' and 'sentenceEnd'.
Controller:
#RequestMapping(value = "/{match_id}", method = RequestMethod.GET)
public Match getMatch(#PathVariable("match_id") long matchId) {
long start = System.currentTimeMillis();
LOGGER.info("REQUESTED RETRIEVAL OF MATCH WITH ID: " + matchId);
Match match = matchRepository.findOneById(matchId);
match.setActualText(matchRepository.getText(match.getId()));
match.setSentenceStart(matchRepository.getSentenceStart(match.getId()));
match.setSentenceEnd(matchRepository.getSentenceEnd(match.getId()));
match.setSentenceID(matchRepository.getSentenceId(match.getId()));
long end = System.currentTimeMillis();
LOGGER.info("DONE. TOOK " + (end - start) + " MILLISECONDS.");
return match;
} //getMatch()
Repository:
public interface MatchRepository extends JpaRepository<Match, Long>, JpaSpecificationExecutor<Match> {
#Query(value = "SELECT match_in_sentence_start FROM vTextMatch where match_id = :m_id LIMIT 1",
nativeQuery = true)
int getSentenceStart(#Param("m_id") long matchId);
#Query(value = "SELECT match_in_sentence_end FROM vTextMatch where match_id = :m_id LIMIT 1",
nativeQuery = true)
int getSentenceEnd(#Param("m_id") long matchId);
}
Model:
#Entity
#Table(name = "match_term")
#JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Match {
#Id
#GeneratedValue
#Column(name = "match_id", nullable = false)
private Long id;
#Column(name = "document_id", nullable = false)
private Long documentId;
#Column(name = "document_start")
private Integer documentStart;
#Column(name = "document_end")
private Integer documentEnd;
#Column(name = "is_meta", nullable = false)
private Boolean isMeta;
#Column(name = "date_inserted", nullable = false)
private Timestamp dateInserted;
#Transient
private String actualText;
#Transient
private int sentenceStart;
#Transient
private int sentenceEnd;
#Transient
private int sentenceID;
/*
|-------------------|
| AUXILIARY METHODS |
|-------------------|
*/
/*
|-------------------|
|SETTERS ANG GETTERS|
|-------------------|
*/
public int getSentenceStart() {
return sentenceStart;
}
public void setSentenceStart(int sentenceStart) {
this.sentenceStart = sentenceStart;
}
public int getSentenceEnd() {
return sentenceEnd;
}
public void setSentenceEnd(int sentenceEnd) {
this.sentenceEnd = sentenceEnd;
}
}
You should investigate line containing #JsonInclude(JsonInclude.Include.NON_EMPTY) - http://fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/fasterxml/jackson/annotation/JsonInclude.Include.html#NON_EMPTY
I would suggest slightly change your design and introduce some message type. You could avoid polluting your domain class with the not needed stuff.
In my application, I am using Spring Data and hibernate as JPA provider to persist and read data.
I have top level Entity class:
#Entity
#Getter #Setter
#Table(name = "operation")
#Inheritance(strategy = InheritanceType.JOINED)
#EqualsAndHashCode(of = {"operationId"})
public abstract class Operation implements Serializable {
public static final int OPERATION_ID_LENGTH = 20;
#Id
#Column(name = "operation_id", length = OPERATION_ID_LENGTH, nullable = false, columnDefinition = "char")
private String operationId;
#Column(name = "operation_type_code")
#Getter(AccessLevel.NONE)
#Setter(AccessLevel.NONE)
private String operationTypeCode;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "begin_timestamp", nullable = false)
private Date beginTimestamp = new Date();
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "end_timestamp")
private Date endTimestamp;
#Column(name = "operation_number", length = 6, columnDefinition = "char")
private String operationNumber;
#Enumerated(EnumType.STRING)
#Column(name = "operation_status", length = 32, nullable = false)
private OperationStatus status;
#ManyToOne(optional = false)
#JoinColumn(name = "user_id")
private User user;
#ManyToOne
#JoinColumn(name = "terminal_id")
private Terminal terminal;
#Column(name = "training_mode", nullable = false)
private boolean trainingMode;
}
For inherited class I have corresponding repository:
public interface ConcreteOperationRepository extends JpaRepository<ConcreteOperation, String> {
#Query("SELECT o FROM ConcreteOperation o WHERE o.beginTimestamp BETWEEN :from AND :to AND o.status = :status AND o.terminal.deviceId = :deviceId AND o.trainingMode = :trainingMode")
Collection<ConcreteOperation> findOperations(#Param("from") Date startDay,
#Param("to") Date endDay,
#Param("status") OperationStatus status,
#Param("deviceId") String deviceId,
#Param("trainingMode") boolean trainingMode);
}
And I have integration test with following method:
#Transactional
#Test
public void shouldFindOperationByPeriodAndStatusAndWorkstationId() {
Date from = new Date(Calendar.getInstance().getTime().getTime());
List<String> terminalIds = loadTerminalIds();
List<OperationStatus> typeForUse = Arrays.asList(OperationStatus.COMPLETED,
OperationStatus.LOCKED, OperationStatus.OPEN);
int countRowsForEachType = 3;
int id = 100001;
for (String terminalId : terminalIds) {
for (OperationStatus status : typeForUse) {
for (int i = 0; i < countRowsForEachType; i++) {
concreteOperationRepository.save(createConcreteOperation(status, terminalId,
String.valueOf(++id)));
}
}
}
Date to = new Date(Calendar.getInstance().getTime().getTime());
for (String terminalId : terminalIds) {
for (OperationStatus status : typeForUse) {
Collection<ConcreteOperation> operations =
concreteOperationRepository.findOperations(from, to, status, terminalId, false);
assertEquals(countRowsForEachType, operations.size());
}
}
}
But this test fails when I using MySql database due to empty result (but passes when I switch to HSQLDB)
Also, this test passes if I put delay "Thread.sleep(1000)" for one second at the beginning of the test, just after the first line.
When I execute SQL from Hibernate log it gives me right result. What's wrong with my code?
In JPA, the Date requires a temporal hint. Normally, you could set the TemporalType when setting the JPA Query parameter:
query.setParameter("from", from), TemporalType.TIMESTAMP);
With Spring Data you need to use the #Temporal annotation, so your query becomes:
#Query("SELECT o FROM ConcreteOperation o WHERE o.beginTimestamp BETWEEN :from AND :to AND o.status = :status AND o.terminal.deviceId = :deviceId AND o.trainingMode = :trainingMode")
Collection<ConcreteOperation> findOperations(
#Param("from") #Temporal(TemporalType.TIMESTAMP) Date startDay,
#Param("to") #Temporal(TemporalType.TIMESTAMP) Date endDay,
#Param("status") OperationStatus status,
#Param("deviceId") String deviceId,
#Param("trainingMode") boolean trainingMode
);
I realized my problem. The problem was due to difference of precision between type of field in MySql (default timestamp precision cut of milliseconds) and Java date (with milliseconds)
I've altered my table:
ALTER TABLE transaction modify end_timestamp TIMESTAMP(6)
and that's solved my problem.