I have this Pojo:
private long id;
#NotEmpty
#JsonProperty("name")
private String name;
#NotEmpty
#JsonProperty("id")
private String tagUuid;
#NotEmpty
#JsonProperty("archived")
private boolean archived;
#NotEmpty
#JsonProperty("creationDate")
private DateTime creationDate;
private Integer count;
#JsonCreator
public Tag() {
}
public Tag(long id, String tagUuid, String name, boolean archived, Timestamp creationDate, Integer count) {
this.id = id;
this.tagUuid = tagUuid;
this.name = name;
this.archived = archived;
this.creationDate = new DateTime(creationDate);
this.count = count;
}
This is my result set mapper:
public class TagMapper implements ResultSetMapper<Tag> {
#Override
public Tag map(int index, ResultSet r, StatementContext ctx) throws SQLException {
return new Tag(
r.getLong("id"),
r.getString("tag_uuid"),
r.getString("name"),
r.getBoolean("archived"),
r.getTimestamp("creation_date"),
r.getInt("count")
);
}
}
How can I fetch from the database one column less. For example in some queries I fetch only tagUuid and name and not the other fields.
But if I do this I get this exception: org.skife.jdbi.v2.exceptions.ResultSetException: Exception thrown while attempting to traverse the result set. I tried to create a addtional Tag Constructor without the other parameters.
This is the query I try to run:
#SqlQuery("SELECT t.id, t.tag_uuid as tag_uuid, t.name, t.archived, t.creation_date FROM tags t WHERE t.tag_uuid = :tag_uuid LIMIT 1")
public Tag fetchTagByUuid(#Bind("tag_uuid") String tagUuid);
You can just return the extra column in your query SQL.
#SqlQuery("SELECT t.id, t.tag_uuid as tag_uuid, t.name, t.archived, " +
"t.creation_date, 0 AS count FROM tags t " +
"WHERE t.tag_uuid = :tag_uuid LIMIT 1")
public Tag fetchTagByUuid(#Bind("tag_uuid") String tagUuid);
You can retrieve the values whatever you want and before passing the values to Tag constructor check their existence in the ResultSet. If the attribute is not present then you can pass the default value for the attributes.
You can check the value as r.getString("tag_uuid") != null (for strings)
then tag_uuid = r.getString("tag_uuid")
Related
So im developing an app that has localization support, so my db has localizations.
I have this query (using #Query annotation):
select new com.fullstack.daos.projections.LocalizedTutorialDAO(t.id, t.created, t.createdBy, t.lastModified, t.lastModifiedBy, t.version, t.exclusive, (VALUE(l)).name, (VALUE(l)).description, tp) from tutorial t join t.localizations l join t.topics tp where (VALUE(l)).name like %:name% and (KEY(l)) = :lang
If i don't include the t.topics it works perfectly fine, but if i do, it gives me:
Caused by: javax.persistence.NonUniqueResultException: query did not return a unique result: 3
The thing is, thats supposed to happen, see the t.topics is a set of string representing an #ElementCollection. When i do the default findById it fetches it, why cant my projection in this case convert the so called "non unique result" to the Set it is supposed to be?
public class LocalizedTutorialDAO {
private UUID id;
private LocalDateTime created;
private String createdBy;
private LocalDateTime lastModified;
private String lastModifiedBy;
private int version;
private String name, description;
private Set<String> topics = new HashSet<>();
public LocalizedTutorialDAO(UUID id, LocalDateTime created, String createdBy, LocalDateTime lastModified,
String lastModifiedBy, int version, boolean exclusive, String name, String description, String topics) {
super(id, created, createdBy, lastModified, lastModifiedBy, version);
this.name = name;
this.description = description;
this.topics = topics;
}
}
I am developing a spring boot rest api, in that case when i am using a custom query from repository it is returning a null list, and the worst thing is there in no exception on eclipse console.
**** Another Thing**********
I have another controller having different service and repository, that is working correctly.
Entity
#Entity
#Table(name="Navigation_Master")
public class Navigation_Master {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="Nav_ID")
private int Nav_ID;
#Column(name="Nav_TS_ID")
private int Nav_TS_ID;
#Column(name="Nav_Application_ID")
private int Nav_Application_ID;
#Column(name="Nav_Page_ID")
private int Nav_Page_ID;
#Column(name="Nav_Reg_ID")
private int Nav_Reg_ID;
#Column(name="Nav_UnloadEvent")
private String Nav_UnloadEvent;
#Column(name="Nav_RedirectEvent")
private String Nav_RedirectEvent;
#Column(name="Nav_AppCache")
private String Nav_AppCache;
#Column(name="Nav_TTFB")
private String Nav_TTFB;
#Column(name="Nav_Processing")
private String Nav_Processing;
#Column(name="Nav_DomInteractive")
private String Nav_DomInteractive;
#Column(name="Nav_DomComplete")
private String Nav_DomComplete;
#Column(name="Nav_ContentLoad")
private String Nav_ContentLoad;
#Column(name="Nav_PageLoad")
private String Nav_PageLoad;
#Column(name="Nav_EntrySyetemTimes")
private Timestamp Nav_EntrySyetemTimes;
// Getter & setter $ constructors
}
Controller:
#GetMapping("/getNavs/{tcId}/{appid}/{pageId}/{uId}")
public List<Navigation_Master> findPageByName(#PathVariable("appid") String appid, #PathVariable("pageId") String pageId, #PathVariable("tcId") String tcId,
#PathVariable("uId") String uId) {
return navigation_MasterService.getTopOneNavigation(tcId, appid, pageId, uId);
}
Service:
#Override
public List<Navigation_Master> getTopOneNavigation(String appid, String pageId, String tcId, String uId) {
System.out.println(appid+" " + pageId + " "+ tcId + uId);
return navigation_MasterReposity.findNavByParam(Integer.parseInt(tcId), Integer.parseInt(appid), Integer.parseInt(pageId), Integer.parseInt(uId));
}
Repository:
public interface Navigation_MasterReposity extends JpaRepository<Navigation_Master, Integer> {
#Query(value="select * from Navigation_Master p where p.Nav_TS_ID=:tcid and p.Nav_Application_ID=:apid and p.Nav_Page_ID=:pgid and p.Nav_Reg_ID=:uid order by p.Nav_ID desc", nativeQuery=true)
List<Navigation_Master> findNavByParam(#Param("tcid") int tcid,
#Param("apid") int apid,
#Param("pgid") int pgid,
#Param("uid") int uid);
}
in case when i am running this i am getting an empty list. please help me solve the issue, Thanks in advance.
Check from the console/logs if the requested query is correct with the right values in the binding parameters.
To see the sql and the binding parameters, add these 2 lines in application.properties/yaml:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
Cheers
I already have such an error, when you try to perform unapropriate matching (date to boolean, and so) which I had been able to fix quite easilly.
But this time, I am quite confused, because hibernate refuses to match a "numeric" Id to a Java "Long" (and it also failed when setter is made for Double, Integer, Float, String, int, long, etc.)
The sql-server field "id" is a NUMERIC(19,0)
My DTO is :
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
public class DtoResult {
private Long id;
private String name;
// ...
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
My hibernate query :
final SQLQuery query= getCurrentSession().createSQLQuery(select + from + where);
query.setParameter("manyFields", manyFields);
query
.addScalar("id")
.addScalar("name")
.setResultTransformer(Transformers.aliasToBean(DtoResult.class));
return query.list(); // List<DtoResult>
Error:
IllegalArgumentException occurred while calling setter for property [com.some.thing.DtoResult.id (expected type = java.lang.Long)]; target = [com.some.thing.DtoResult#77a70b79], property value = [269895]
I am really puzzled about this, thus any help is welcome.
Thanks for reading untill there.
Just add the expected type, like:
.addScalar("id", new LongType())
.addScalar("name", new StringType())
The number from database query is not Long but BigInteger.
Change setter to:
public void setId(final Number id) {
this.id = id != null ? id.longValue() : null;
}
I need to make an hibernate SQLQuery with db2 and this query is returning me some fields which are calculated and have no relation with any columns in database.
The goal is setting the values of these sum() calculations from SQLQuery on three new transient fields in a Java Object which already existed.
The SQLQuery uses the syntax:
SELECT id as {entityObject.id},
name as {entityObject.name},
order as {entityObject.order},
SUM(CASE
WHEN pv.value_id = 1
AND pv.value=1 THEN 1 ELSE 0 END) AS {entityObject.someCount}
The problem is that Hibernate complains and says to need a column for someCount. It seems not to help declaring the java field as transient or even using the #Transient annotation from javax.persistence at the same time.
If I only declare in the hbm.xml mapping file:
<property name="id" type="java.lang.Integer" column="someColumn" />
<!-- Some more fields here -->
<!-- THE IMPORTANT ONE -->
<property name="someCount" type="java.lang.Integer"/>
Java Object:
public class EntityObject implements Serializable {
private static final long serialVersionUID = 1479579608940145961L;
private Integer id;
private String name;
private Integer order;
// This is the one giving me hell. I've tried with #Transient also
private transient Integer someCount;
public Category() {
}
public Category(final String name, final Integer order) {
this.name = name;
this.order = order;
}
public Integer getOrder() {
return this.order;
}
public void setOrder(final Integer order) {
this.order = order;
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public Integer getSomeCount() {
return someCount;
}
public void setSomeCount(final Integer count) {
this.someCount = count;
}
}
It asks me for a column, and I have tried inserting a fake column and it does not work. The thing is that I want these 'count' fields only to be set from the SQLQuery and to be empty and null when coming from a regular Hibernate Query.
I have looked at the docs and googled, and it seems that you can declare a field transient by only not declaring it at the hibernate mapping file, but then it does not set it on the object with the "as {entityObject.someCount}" even when I have getters/setters declared.
Help please.
Thanks very much in advance.
The only option available that might do all this directly from the Database without having to issue additional queries is a Hibernate Formula property:
http://wiki.jrapid.com/w/Formula_(attribute_of_property)
<property name="someCount" formula="select count(*) from some_table where table_key = ?"/>
The ? placeholder will be populated automatically with the ID of the current instance.
1 Create a POJO:
public class SumValue{
private BigInteger myId;
private String myName;
private BigInteger myOrder;
private BigInteger mySum;
....
getters and setters here
....
}
2 Minor changes in your query
SELECT id as "myId",
name as "myName",
order as "myOrder",
SUM(CASE
WHEN pv.value_id = 1
AND pv.value=1 THEN 1 ELSE 0 END) AS "mySum"
3 Execute native sql
List<SumValue> jobStateViewList = (List<SumValue>)getSessionFactory().getCurrentSession()
.createSQLQuery(yourQuery)
.setResultTransformer(
new AliasToBeanResultTransformer(SumValue.class)
).list();
I have an Invoice Class like this:
Invoice {
int id;
Set<Attachment> attachments;}
The Attachment class:
Attachment {
int id;
Status status;}
And, The Status class:
Status {
int id;
String desc;}
I want to build a method that given a status element, of an Attachment, return all related invoices.
This is my method:
public List<Invoice> findbyCriteria(Invoice criteria, int init,
int pageSize, String orderBy, String ascDesc) {
Criteria c = getSession().createCriteria(Invoice.class).
add(Example.create(criteria));
if(criteria.getAttachment() !=null && criteria.getAttachment().size() > 0)
c.createCriteria("attachments").add(Example.create((Set<Attachment>)criteria.getAttachments()));
return c.list();
But this returns a ClassCastException during creation the Example:
Example.create((Set<Attachment>)criteria.getAttachments()));
What is wrong?
Thanks!
try this:
List<Invoice> invoices = sess.createCriteria(Invoice.class)
.add(what you need to filter)
.createCriteria("attachments").add(what you need to filter)//like Restrictions.like("name", "F%")
.createCriteria("status").add(what you need to filter).list();