I'm working with Mybatis 3.2.6 and implementing a custom resulthandler. I've done this before using a simple datatype parameter and have had no problems. This time around I need to pass in several arguments... The signature I'm using is
session.select(statement, parameter, handler);
For parameter I've created a simple POJO to easily send in what I need. It is as follows:
public class DifferenceParam {
private int current;
private int compare;
private String table;
private String comparator;
/**
* Constructor excluding comparator. Will default a value of
* "code" to compare content on, e.g., <br/>
* {#code select * from a minus select * from b where a.code = b.code } <br/>
* #param table
* #param current
* #param compare
*/
public DifferenceParam(String table, int current, int compare) {
this(table, "code", current, compare);
}
/**
* Constructor providing a specific column to compare on, e.g. <br/>
* {#code select * from a minus select * from b where a.[comparator] = b.[comparator] } <br/>
* #param table
* #param comparator
* #param current
* #param compare
*/
public DifferenceParam(String table, String comparator, int current, int compare) {
this.table = table;
this.comparator = comparator;
this.current = current;
this.compare = compare;
}
/** Appropriate setters and getters to follow **/
}
The handler implementation is irrelevant at the moment, because I get an exception well in advance... The query I'm executing is:
<select id="getCodeSetModifications" parameterType="DifferenceParam" resultType="Code">
select *
from
(
select * from ${param.table} where revision_seq = #{param.current}
minus
select * from ${param.table} where revision_seq = #{param.compare}
) a, ${param.table} b
where a.${param.comparator} = b.${param.comparator}
and b.revision_seq = #{param.compare}
</select>
Here is the interface as well
public List<Code> getCodeSetModifications(#Param("param") DifferenceParam param);
The problem I'm having is that execution via a mapper e.g.,
session.getMapper(DifferenceParam.class);
works just fine, but when I invoke through a select on the session I get the following exception.
Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'param' in 'class com.mmm.his.cer.cerval.uidifference.map.param.DifferenceParam'
Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'param' in 'class com.mmm.his.cer.cerval.uidifference.map.param.DifferenceParam'
I've debugged as far as I can go into Mybatis, but am having no luck.
Thanks in advance...
When you use session.getMapper(DifferenceParam.class);, mybatis looks for #Param annotation and uses it's value in query.
When you invoke session.select(statement, parameter, handler);, such mapping doesn't occur.
Try to add public DifferenceParam getParam() { return this; } to DifferenceParam to workaround this.
when the MyBatis query only have one param. Don't need #{param.} reference.
because it default use the only param.
so when u use ${param.table}, it actually using #{DifferenceParam.param.table}.
because it think the ${param.} inside of the #{DifferenceParam.}
Related
I have an enum codes in JAVA. I convert all JAVA code to DELPHI.
I almost done, but i stucked in here. I have no idea, how to convert enum to Delphi.
I am wondering, this code can be convert to Delphi ?
/**
* Enum describing the databin class ID's. Methods exist for getting the
* KakaduClassID and the StandardClassID. I have also included the string
* representations of the databins as defined for cache model updates.
*
*
*/
public enum JPIPDatabinClass {
/** Precinct data bin class. */
PRECINCT_DATABIN(KakaduConstants.KDU_PRECINCT_DATABIN, JPIPConstants.PRECINCT_DATA_BIN_CLASS, "P"),
/** Tile Header data bin class. */
TILE_HEADER_DATABIN(KakaduConstants.KDU_TILE_HEADER_DATABIN, JPIPConstants.TILE_HEADER_DATA_BIN_CLASS, "H"),
/** Tile data bin class. */
TILE_DATABIN(KakaduConstants.KDU_TILE_DATABIN, JPIPConstants.TILE_DATA_BIN_CLASS, "T"),
/** Main Header data bin class. */
MAIN_HEADER_DATABIN(KakaduConstants.KDU_MAIN_HEADER_DATABIN, JPIPConstants.MAIN_HEADER_DATA_BIN_CLASS, "Hm"),
/** Meta data bin class. */
META_DATABIN(KakaduConstants.KDU_META_DATABIN, JPIPConstants.META_DATA_BIN_CLASS, "M");
/** The classID as an integer as per the Kakadu library. */
private int kakaduClassID;
/** The classID as an integer as per the JPEG2000 Part-9 standard. */
private int standardClassID;
/**
* The classID as a string as per the JPEG2000 Part-9 standard. Used for
* cache model updates.
*/
private String jpipString;
/**
* Constructor.
*
* #param _kakaduClassID
* #param _standardClassID
* #param _jpipString
*/
JPIPDatabinClass(int _kakaduClassID, int _standardClassID, String _jpipString) {
kakaduClassID = _kakaduClassID;
standardClassID = _standardClassID;
jpipString = _jpipString;
}
/** Returns the classID as an integer as per the Kakadu library. */
public int getKakaduClassID() {
return kakaduClassID;
}
/** Returns the classID as an integer as per the JPEG2000 Part-9 standard. */
public int getStandardClassID() {
return standardClassID;
}
/**
* Returns the classID as a string as per the JPEG2000 Part-9 standard. Used
* for cache model updates.
*/
public String getJpipString() {
return jpipString;
}
};
This Enum can easily be translated to a plain old Delphi class which has a three-argument constructur like the Java Enum, and three read-only public properties.
JPIPDatabinClass = class(TObject)
private
...
public
constructor Create(AKakaduClassID: Integer; AStandardClassID: Integer; AJPIP: string);
property KakaduClassID: Integer; read FKakaduClassID;
property StandardClassID: Integer; read FStandardClassID;
property JPIP: string; read FJPIP;
end;
and 'singleton style' instances:
function PRECINCT_DATABIN: JPIPDatabinClass;
function TILE_HEADER_DATABIN: JPIPDatabinClass;
...
implementation
var
FPRECINCT_DATABIN: JPIPDatabinClass;
FTILE_HEADER_DATABIN: JPIPDatabinClass;
...
FPRECINCT_DATABIN := JPIPDatabinClass.Create( ... );
FTILE_HEADER_DATABIN := JPIPDatabinClass.Create( ... );
...
function PRECINCT_DATABIN: JPIPDatabinClass;
begin
Result := FPRECINCT_DATABIN;
end;
function TILE_HEADER_DATABIN: JPIPDatabinClass;
begin
Result := FTILE_HEADER_DATABIN;
end;
...
Note: the disadvantage of this approach is that does not create real Delphi enum types, it only emulates the Java enum type as immutable Delphi objects.
I have been given the exiciting job to add some javadoc to some code.
so here is my Q:
what is the right way to write javadoc for this constructor.
public Match(int MatchID, int MatchRound, int HomeTeamID, int GuestTeamID, boolean IsPlayed) {
this.isPlayed = IsPlayed;
this.matchID = MatchID;
this.matchRound = MatchRound;
this.homeTeamID = HomeTeamID;
this.guestTeamID = GuestTeamID;
}
I wouldn't write any, because it's obvious.
I would rename all the parameters to follow Java conventions, though.
Here is the formatted Javadoc:
/**
* Constructor for creating a new match.
* #param MatchID the id of the match
* #param MatchRound the round for the match
* #param HomeTeamID the id of the home team
* #param GuestTeamID the id of the guest team
* #param IsPlayed whether or not the match is played
*/
public Match(int MatchID, int MatchRound, int HomeTeamID, int GuestTeamID, boolean IsPlayed) {
In Eclipse you can just type /** above the constructor and it will generate the Javadoc template automatically.
As topic states, I want to remove non-objects from List of objects.
I have a web service (xml file with some data) and generated classes from XSD file. Among generated XSD classes there is a class ASMENYS and it has method getContent(). This method returns a list of generated.ASMUO objects.
Now the problem is, that this method for some reason returns empty lines (spaces?) among objects. I need to iterate through asmenysList, and because of empty spaces I'm forced to use if() which deprecates my code performance...Any ideas? Why are those empty spaces generated? Or maybe some ideas how to better filter them without iteration if possible?
//m here is generated.ASMENYS object,.: generated.ASMENYS#10636b0
List<Object> asmenysList = ((ASMENYS) m).getContent();
System.out.println(asmenysList);
[
, generated.ASMUO#1799640,
, generated.ASMUO#b107fd,
, generated.ASMUO#10636b0,
...
, generated.ASMUO#1df00a0,
]
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"content"
})
#XmlRootElement(name = "ASMENYS")
public class ASMENYS {
#XmlElementRef(name = "ASMUO", type = ASMUO.class, required = false)
#XmlMixed
protected List<Object> content;
/**
* Gets the value of the content property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the content property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getContent().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link ASMUO }
* {#link String }
*
*
*/
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
}
EDIT
/**
* Gets the value of the asmId property.
*
*/
public int getAsmId() {
return asmId;
}
List<Object> asmenysList = ((ASMENYS) m).getContent();
for(Object asm : asmenysList){
//trying to cast empty asmenysList element, gives me an error.
//that's why I'm forced to use if() as I said before.
if(asm.getClass().getName() == "generated.ASMUO"){
int asm_id = ((ASMUO) asm).getAsmId();
}
}
By definition a List<Object> only holds Object(s). If there are primitive types in there, they must be autoboxed. If it's an array, that is an Object. The only empty spaces I see are from the toString() method of List.
Edit
based on your edit,
if(asm.getClass().getName() == "generated.ASMUO"){
Is not how you test String equality,
if(asm.getClass().getName().equals("generated.ASMUO")) {
For a GeoSPARQL test project I want to have a custom datatype set in Jena. Howerver when I try this through the example provided at the Jena website, it still doesn't work. I get the following result:
_:b0 <http://www.opengis.net/ont/geosparql#asWKT> "POINT (52.83525867111958 6.870789811954563)^^http://www.opengis.net/ont/sf#wktLiteral "^^<java:com.hp.hpl.jena.rdf.model.impl.LiteralImpl> .
And of course I don't want the java:com.hp.hpl.jena.rdf.model.impl.LiteralImpl but http://www.opengis.net/ont/sf#wktLiteral because I wan to work with GeoSPARQL. On this page they have example data that works perfectly with my triple store and spatial index. But the above data doesn't work at all with spatial indexing.
So, my question is, I do I define a custom datatype in my RDF in Jena?
The syntax is
"POINT (52.83525867111958 6.870789811954563)"^^<http://www.opengis.net/ont/sf#wktLiteral>
I just found the answer to my question after a lot of trial and error. To add a custom RDFDatatype to my RDF model I first had to create my own class which extends BaseDatetype and which I called WktLiteral, looking like this:
public class WktLiteral extends BaseDatatype {
public static final String TypeURI = "http://www.opengis.net/ont/sf#wktLiteral";
public static final String CRS84 = "<http://www.opengis.net/def/crs/OGC/1.3/CRS84>";
public static final RDFDatatype wktLiteralType = new WktLiteral();
private WktLiteral() {
super(WktLiteral.TypeURI);
}
/**
* Convert a value of this datatype out
* to lexical form.
*/
public String unparse(Object value) {
return value.toString();
}
/**
* Parse a lexical form of this datatype to a value
*/
public Object parse(String lexicalForm) {
return new TypedValue(String.format("%s %s", WktLiteral.CRS84, lexicalForm), this.getURI());
}
/**
* Compares two instances of values of the given datatype.
* This does not allow rationals to be compared to other number
* formats, Lang tag is not significant.
*
* #param value1 First value to compare
* #param value2 Second value to compare
* #return Value to determine whether both are equal.
*/
public boolean isEqual(LiteralLabel value1, LiteralLabel value2) {
return value1.getDatatype() == value2.getDatatype()
&& value1.getValue().equals(value2.getValue());
}
Where it was quite important to return a TypedLiteral in the parse() method. After which I had to do the following to add something to my RDF model:
TypeMapper.getInstance().registerDatatype(WktLiteral.wktLiteralType);
item.addLiteral(GeoSPARQL.asWKT, ResourceFactory.createTypedLiteral(geom, WktLiteral.wktLiteralType));
Where GeoSPARQL.asWKT is the predicate in the GeoSPARQL vocabulary that I generated through schemagen. geom is the geometry object as well known text and WktLiteral.wktLiteralType is an instance of the above class.
In conclusion the result was the following (notation 3):
_:b0 <http://www.w3.org/2003/01/geo/wgs84_pos#lat_long> "POINT (51.61821756986111 5.542408362751153)" .
thus exactly what I wanted... Thanks for all the input.
I'm trying to use GROUP BY in my criteria. I need to do this:
SELECT b FROM Book b GROUP BY volumeCode;
I have following code:
Criteria c = s.createCriteria(Book.class);
c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
List<Book> result = c.list();
But this criteria returns only volumeCodes (a list of Strings). I need to get a list of Books. So I tried to use Transformers:
Criteria c = s.createCriteria(Book.class);
c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
c.setResultTransformer(Transformers.aliasToBean(Book.class));
List<Book> result = c.list();
This code returns list of null values. Is it possible to do that with criteria?
First of all, the projecton filters the amount of data retrieved, if you want more data, you should add those properties to the projection too.
Example:
c.setProjection( Projections.projectionList()
.add( Projections.property("id").as("id") )
.add( Projections.property("descripction").as("description") )
.add( Projections.groupProperty("volumeCode").as("volumeCode") ));
Now, the transformer does what it says "Alias to Bean", it does an alias match with the properties of your java bean "Book.java".
Edit:
Without the transformer, if the projection has more than one property, the result comes out like this:
for(Object[] item:criteria.list()){
System.out.println( (String)item[0] ); //ID
System.out.println( (String)item[1] ); //Description
System.out.println( (String)item[2] ); //Volume code
}
Thats why you were getting the cast exception, about the transformer, try to match every alias with the property name of your java bean.
cz_Nesh.
sorry about my first answer.
i read Hibernate api and read some Hibernate source code i find that.
if you use this code
session.createCriteria(EmpUserImpl.class).list();
it will return List EmpUserImpl.
if you use this code
criteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("company").as("company"))
.add(Projections.property("name").as("name"))
.add(Projections.property("company").as("company")));
List list = criteria.list();
it will return List ,is not List EmpUserImpl why?
i see the criterion's parent class CriteriaSpecification i find that .
public interface CriteriaSpecification {
/**
* The alias that refers to the "root" entity of the criteria query.
*/
public static final String ROOT_ALIAS = "this";
/**
* Each row of results is a <tt>Map</tt> from alias to entity instance
*/
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE;
/**
* Each row of results is an instance of the root entity
*/
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE;
/**
* Each row of results is a distinct instance of the root entity
*/
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE;
/**
* This result transformer is selected implicitly by calling <tt>setProjection()</tt>
*/
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE;
/**
* Specifies joining to an entity based on an inner join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#INNER_JOIN}
*/
#Deprecated
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue();
/**
* Specifies joining to an entity based on a full join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#FULL_JOIN}
*/
#Deprecated
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue();
/**
* Specifies joining to an entity based on a left outer join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}
*/
#Deprecated
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue();
}
can you see the public static final ResultTransformer PROJECTION ? it say that This result transformer is selected implicitly by calling setProjection()
is mean when you use criteria.setProjection,the result will not List EmpUserImpl,because ResultTransformer is change to "PROJECTION" from "ROOT_ENTITY".it will packaging by Projection(like select name,oid .. ).
so, if you want to return List EmpUserImpl you need set Projections.property("name").as("name").,(if you need name just set name).
this is my code .
Criteria criteria = session.createCriteria(EmpUserImpl.class);
criteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("company").as("company"))
.add(Projections.property("name").as("name"))
.add(Projections.property("company").as("company")));
criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class));
List<EmpUserImpl> list = criteria.list();
for (EmpUserImpl empUserImpl : list) {
System.out.println(empUserImpl.getName());
}
it can work . i hope it can help you.
I think you can use : criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);