How to check parameter existance in myBatis mapper XML? - sql

I simplifed my problem as following code.
Mapper Interface looks like:
#Mapper
public interface TestMapper {
public Integer countTable(#Param("tValue1") Integer tValue1);
public Integer maxTable(#Param("tValue2") Integer tValue2);
}
Mapper Xml looks like:
<sql id="sql_where">
<where>
<if test="tValue1 != null">tValue1 = #{tValue1}</if>
<if test="tValue2 != null">AND tValue2 = #{tValue2}</if>
<where>
</sql>
<select id="countTable" resultType="Integer">
SELECT COUNT(*) FROM TestTable
<include refId="sql_where"/>
</select>
<select id="maxTable" resultType="Integer">
SELECT MAX(*) FROM TestTable
<include refId="sql_where"/>
</select>
when countTable or maxTable method is called, BindingException occurs.
Due to one of parameter is not found.
How can I check the parameter exists in XML?
I could've insert all params to method, but I don't want programmers to be confused (they're not going to be used)

Related

fluent validation, use multiple parameters for validation

I have the following xml.
<AttributeSet>
<KeyName>accountType</KeyName>
<KeyValue><val>administrator</val><val>developer</val></KeyValue>
<!-- valid values are String, Binary and Email, Datetime -->
<AttributeType>String</AttributeType>
<Desc>Type of Account for the owning user</Desc>
<Mandatory>True</Mandatory>
<PrimaryKey>False</PrimaryKey>
<LocalUnique>False</LocalUnique>
<GlobalUnique>False</GlobalUnique>
<CaseSensitive>True</CaseSensitive>
<ValidSet Lookup="False">
<TableLookup>Lookup</TableLookup>
<ColumnLookup>AccountType</ColumnLookup>
</ValidSet>
<Size>
<Min>1</Min>
<Max>8</Max>
</Size>
<Resusable>False</Resusable>
</AttributeSet>
I pass it to fluentvalidation which requires that the KeyValue must be checked for rules
like
1) <Mandatory>True</Mandatory> if this is true the keyvalue must exist.
2) <Size>
<Min>1</Min>
<Max>8</Max>
</Size>
keyvalue size must be between these values.
my code:
public class RecordValidator : AbstractValidator<Entity.EigenData.Record>
{
public RecordValidator()
{
//first match
RuleFor(rec => rec.KeyName).NotNull();
}
}
I really donot know how to check the min max and mandatory values using fluent rules.
any body can point?

I encounter NoSuchMethodException myclass<init>() in mapper file for myBatis

I am trying to embed myBatis database structure to my existing project. I have already implemented it as an example. When I try to use same methods on my project, I am getting this NoSuchMethodException.
(by the way, this sql query works, I have already tried it on database with same values)
My class file
public class Cashflow {
public long id;
public LocalDate finalMaturityDate;
public int branchCode;
public int currencyCode;
public long rateProfileCodeId;
public Cashflow(long id, LocalDate finalMaturityDate) {
this.id = id;
this.finalMaturityDate = finalMaturityDate;
}
public Cashflow(long id, int branchCode, int currencyCode, long rateProfileCodeId){
this.id = id;
this.branchCode = branchCode;
this.currencyCode = currencyCode;
this.rateProfileCodeId = rateProfileCodeId;
this.finalMaturityDate = LocalDate.parse("2012-05-12");
}
public void setRateProfileCodeId(long rateProfileCodeId) {
this.rateProfileCodeId = rateProfileCodeId;
}
}
My mapper file:
<resultMap type="Cashflow" id="CashflowResult">
<result property="id" column="NAK_ID" />
<result property="branchCode" column="NAK_GIR_SUBE_KODU" />
<result property="currencyCode" column="NAK_DOVIZ_KODU" />
<result property="rateProfileCodeId" column="NAK_OPK_ID" />
</resultMap>
<select id="retrieveCashflowMyBatis" parameterType="long" resultMap="CashflowResult" >
SELECT
NAK_ID,
NAK_DOVIZ_KODU,
NAK_OPK_ID,
NAK_URN_ID,
NAK_GIRIS_TIP,
NAK_AKIS_TUTAR,
NAK_GIR_SUBE_KODU,
NAK_REFERANS_NO,
NAK_GECERLILIK_TARIH,
NAK_DURUM_KODU,
NAK_DETAY_GUNCELLEME,
MUI_MUSTERI_NO,
NAH_ODEME_BAS_TARIH,
NAH_ORTALAMA_VADE_TARIH,
NAH_ORTALAMA_VADE,
NAH_HESAPLAMA_TARIH,
NAH_DURASYON,
NAH_IRR,
NAH_FAIZ_HESAP_TIPI,
NAH_DURASYON_BAZ_TARIH,
NAH_KALAN_ORTALAMA_VADE,
NAH_FAIZ_TIPI,
OPK_LIBOR_BASAMAK_SAYISI,
OPK_ORAN_GUN_KODU,
OPK_GERI_ODEME_VALOR
FROM SCNAU.NAU_NAKIT_AKIS
LEFT OUTER JOIN
SCNAU.NAU_NAKIT_AKIS_HESAP
ON NAK_ID = 35
AND NAH_NAK_ID = NAK_ID,
SCNAU.NAU_MUSTERI_ILISKI,
SCNAU.NAU_ORAN_PROFIL_KOD
WHERE NAK_ID = 35
AND MUI_NAK_REFERANS_NO = NAK_REFERANS_NO
AND MUI_DURUM_KODU = '1'
AND NAK_OPK_ID = OPK_ID
WITH UR
</select>
My interface class for method:
public interface DatabaseService {
public Cashflow retrieveCashflowMyBatis(long cashflowId);
}
Your resultMap is trying to call the default constructor Cashflow() (because you didn't tell it to do something else), which doesn't exist. Either add one...
public Cashflow() {}
...or put the correct contructor parameters into your resultMap:
<resultMap type="Cashflow" id="CashflowResult">
<constructor>
<idArg column="NAK_ID" javaType="int"/>
<arg column=".." javaType=/>
<!-- do for all constructor arguments branchCode, currencyCode, rateProfileCodeId -->
</constructor>
... result tags as needed
</resultMap>

NHibernate GetNamedQuery executes stored procedure but returns empty list

I have a Stored Procedure that returns 2 records when tested in SQL Studio Management Express using this script:
declare #route_id_param as varchar(10), #start_time as datetime, #start_date as datetime, #end_date as datetime
set #start_time = GETDATE()
set #start_date = CONVERT(DATETIME,'10/26/2013',101)
set #end_date = CONVERT(DATETIME,'12/26/2020',101)
exec dbo.sp_get_deactivation_list #companyId=1, #startDate = #start_date, #endDate = #end_date;
select execution_time_in_ms = DATEDIFF(millisecond, #start_time, getdate())
GO
When I attempt to executed same stored procedure from NHibernate, using the following mapping file, I get 0 results.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
assembly="HGT.IridiumAirtime.Service"
namespace="HGT.IridiumAirtime.Service.Model">
<sql-query name="GetDeactivationList" callable="true">
<query-param name="companyId" type="int"/>
<query-param name="startDate" type="DateTime"/>
<query-param name="endDate" type="DateTime"/>
<!--<return class="Activation">
<return-property column="MobileId" name="MobileId" />
<return-property column="RadioAddress" name="RadioAddress" />
<return-property column="DeactivationDate" name="DeactivationDate" />
</return>-->
exec [sp_get_deactivation_list] #companyId=:companyId, #startDate=:startDate, #endDate=:endDate
</sql-query>
</hibernate-mapping>
The method that executed said Stored Procedure is:
public IEnumerable<TOut> ExecuteStoredProcedure<TOut>(string procedureName, IList<SqlParameter> parameters)
{
IEnumerable<TOut> result;
using (var session = _sessionFactory.OpenSession())
{
var query = session.GetNamedQuery(procedureName);
foreach (var parameter in parameters)
{
query.SetParameter(parameter.ParameterName, parameter.Value);
}
AddStoredProcedureParameters(query, parameters);
result = query.List<TOut>();
}
return result;
}
I even created a new mapping file for this Activation type even though there is no associated table but NHibernate does not return the correct result. Un-commenting the type mapping definition within the procedure's mapping file does not change outcome. Am I missing something here?
I get no exceptions, so it looks like procedure is being executed.
UPDATE: 1 Removed call to AddStoredProcedureParameters and replaced with method body.
UPDATE 2 Adding Stored Procedure:
if OBJECT_ID ( 'dbo.[sp_get_deactivation_list]', 'P' ) is not null
drop procedure dbo.[sp_get_deactivation_list];
go
create procedure [dbo].[sp_get_deactivation_list]
#companyId int,
#startDate DateTime,
#endDate DateTime
as
begin
select
assMobileRadio.Mobile_ID as MobileId,
tblRadioinfo.Radio_Address as RadioAddress,
tblRadioinfo.Deactivation_Date as DeactivationDate
from tblRadioinfo
left join assMobileRadio
on tblRadioinfo.Radio_ID = assMobileRadio.Radio_ID
where tblRadioinfo.Radio_Type_ID in (2, 4, 7)
and tblRadioinfo.Company_ID = #companyId
and tblRadioinfo.Deactivation_Date <= #endDate
and tblRadioinfo.Deactivation_Date >= #startDate
and tblRadioinfo.Radio_Address in (select IMEI from [airtime_cdrs] where Effective_Date > #startDate and Effective_Date < #endDate)
from airtimes_cte for xml path('')),1,1,''))
ORDER BY tblRadioinfo.Deactivation_Date
end
I've just tried your mapping (the same as possible) and your 1) mapping and 2) call is OK. Except the fact that I am not sure about the call inside of the AddStoredProcedureParameters
So, this is working:
var query = session.GetNamedQuery("GetDeactivationList");
query.SetParameter("companyId", 1);
query.SetParameter("startDate", new DateTime(2013,10,26));
query.SetParameter("endDate", new DateTime(2020,12,26));
// if the <return class="Activation"> is commented ... we'll get object[]
var list = query.List<object[]>();
And this is working. Other words. Your mapping is working. The SQL call (exec sp) is fired, because if the named query won't be find, or some other issues would happen, we will get an Exception.
The only suspected right now is the black box AddStoredProcedureParameters (could not it switch start and end date?)
I would suggest, do check your Unit test in the SQL Server Profiler, you will see what is passed to DB... and you can take and reexecute.
If executing the stored procedure you have is your main purpose (not exactly using GetNamedQuery), you can use the following:
Assuming that your methods' arguments are: int? id, DateTime? fromDate, DateTime? toDate (all nullable values)
IList<TOut> result = session.CreateSQLQuery("exec [dbo].[sp_get_deactivation_list]:param1, :param2, :param3")
.SetParameter("param1", id, NHibernateUtil.Int32)
.SetParameter("param2", fromDate, NHibernateUtil.DateTime)
.SetParameter("param3", toDate, NHibernateUtil.DateTime)
.SetResultTransformer(Transformers.AliasToBean<TOut>()).List<TOut>();
return result;
And in your mapping file for class TOut, just have the related properties as normal.
If Activation is non-managed entity with nhibernate you can use this:
var query = session.GetNamedQuery(procedureName);
AddStoredProcedureParameters(query, parameters);
result = query.SetResultTransformer(Transformers.AliasToBean(typeof(TOut)))
.List<TOut>();
If does try to add alias:
<return alias="activation" class="Activation">
...
</return>
For example:
<sql-query name="mySqlQuery">
<return alias="person" class="eg.Person">
<return-property name="Name" column="myName"/>
<return-property name="Age" column="myAge"/>
<return-property name="Sex" column="mySex"/>
</return>
SELECT person.NAME AS myName,
person.AGE AS myAge,
person.SEX AS mySex,
FROM PERSON person WHERE person.NAME LIKE :name
</sql-query>
Reference here are some more ways to solve your issue.
Just you need how to say to nhibernate how return the data, "this" column "resolve this" property.
Sorry for my poor english.

ibatis TypeHandlerCallback for multi column mapping - Money object

Ibatis multi column datamapping to type handler.
I have a money object I am using which needs value and currency.
How to map multiple columns to same callbacktype handler?
Java Money object
http://www.javapractices.com/topic/TopicAction.do?Id=13
public class MoneyTypeHandlerCallBack implements TypeHandlerCallback {
//The below works but problems it always defaults currency. I need to be able to get Currency as well to use
// new Money(value, currency ) constructor
#Override
public Object getResult(final ResultGetter getter) throws SQLException {
BigDecimal value = getter.getBigDecimal();
if (value == null) {
return null;
}
Money result = new Money(value); // I need to be able to do new Money (value, currency)
return result;
}
... implment other...
}
SomeView Bean definition:
public class SomeView implements Serializable{
private String companyName
private Money netamount;
// .....geters and setters etc
}
SQLMAP Configurations:
<sqlMap namespace="myspace">
<typeAlias alias="someView" type="com.my.view.someView" />
<resultMap id="some_detail_view" class="someView">
<result property="companyName" column="COMPANY" />
...
<result property="netamount" column="NET_AMT" />
<result property="netamountCurrency" column="NET_AMT_CURRENCY" />
</resultMap>
<select id="someView" parameterClass="java.util.Map"
resultClass="someView" resultMap="some_detail_view">
SELECT COMPANY, NET_AMT, NET_AMT_CURRENCY From......
</select>
</sqlMap>

Hibernate HQL Query : How to set a Collection as a named parameter of a Query with composite key?

Given the following HQL Query:
from Foo foo where foo.id in (:fooIds)
but here i have composite key in the Id ex we have two PK1 and pk2 as Id's.
How can we implement this query..
how can i pass both paramets in setparameters function of query
My question is similar this question
HBM file containing composite key is present below
<?xml version="1.0"?>
<composite-id>
<key-property name="foo1" column="FOO1" type="java.lang.String" length="36"/>
<key-property name="foo2" column="FOO2" type="java.lang.Short" />
</composite-id>
<property name="EffectiveDt" type="java.sql.Date" column="EFFECTIVE_DT" />
<property name="effectiveTypeCd" type="java.lang.String" column="CERT_EFF_TYPE_CD" />
<property name="statusCd" type="java.lang.String" column="CERT_STATUS_CD" />
</class>
Are you using a composite id? Do you have a separate class representing the composite-id or do you have 2 fields in Foo and you want to search using them in your query?
Posting you Foo class would help!
I'm not 100% sure you can use in in this case. One thing you can do is to build the query manually with something like
String hqlQuery = "from Foo foo where "
boolean first = true;
for( ID id : fooids ) {
if( first ) {
hqlQuery += "foo.id = ?";
first = false;
} else {
hqlQuery += " OR foo.id = ?";
}
}
Query q = em.createQuery(hqlQuery);
int position = 0;
for( ID id : fooids ) {
q.setParameter(position, id);
position++;
}
You might want to double check the code, as I'm writing it here, so there's a big chance there's a typo or two.