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

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>

Related

Can you create a Restriction for a Detached Criteria on a primitive collection?

I would like to know if there is a way to create a Restriction on a primitive collection of a Model in NHibernate.3.3.3?
Here's the details:
class Parent {
IEnumerable<string> ChildNames { get; set; }
}
I need to search like so:
private DetachedCriteria BuildQuery() {
var inNames = { "Bob", "Sam", "Dan" };
var query = DetachedCriteria.For<Parent>("parent");
query.Add(Restrictions.In("ChildNames", inNames));
return query;
}
I found this old question that says it's not possible, but given the fact that it's old and doesn't have a ton of upvotes, I'd like to confirm before I refactor.
If I can do it and I'm totally botching it, I'll take that help as well!
In this scenario, we can use Projection (something less type-safe, then mapped Property, but more flexible).
Let's expect the mapping like this:
<bag name="ChildNames" inverse="false" lazy="true" table="[dbo].[ChildNames]"
cascade="all"
batch-size="25">
<key column="ParentId" />
<element type="System.String" column="ChildName" />
</bag>
Then we can adjust the Build query method like this:
protected virtual DetachedCriteria BuildQuery()
{
var inNames = new [] { "Bob", "Sam", "Dan" };
// parent query reference
var query = DetachedCriteria.For<Parent>("parent");
// reference to child query
var child = query.CreateCriteria("ChildNames");
// let's project the column name of the Element, e.g. 'Name'
var columnNameProjection = Projections.SqlProjection(
"ChildName as name", null, new IType[] { NHibernateUtil.String }
);
// in clause
child.Add(Restrictions.In(
columnNameProjection, inNames
));
return query;
}
And this is what we will get:
SELECT ...
FROM Parent this_
inner join [dbo].[ChildNames] childNames3_
on this_.ParentId=childNames3_.ParentId
WHERE ChildName in (#p0, #p1, #p2)
...
#p0=N'Bob',#p1=N'Sam',#p2=N'Dan'
The caveat:
While this is in deed working... the ChildName is used without the Alias. That could be pretty tricky to fulfill... so be careful, if there are more columns with the name ChildName in this scenario
I ended up, like many, refactoring the collection into a strong type.

Convert a SQL query to a Hibernate Criteria expression

I'm having trouble converting this expression to a Criteria expression:
SELECT profile_profiles.profile_sup_id
FROM profil
INNER JOIN profile_profiles ON profile_profiles.profile_id = profil.id
AND profil.id = 4
Can anyone help?
i have one table 'Profil' Many to Many and refelxive
Profil 1 --- profile_profiles --- Profil 2
public class Profil implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String libelle;
private Set<Profil> profiles = new HashSet<Profil>(0);
...
}
hbm
<set name="profiles" table="profile_profiles" cascade="all">
<key column="profile_id" />
<many-to-many column="profile_sup_id" class="com.steriamedshore.proboard.model.referentiel.Profil" />
</set>
Criteria c = session.createCriteria(Profil.class, "profil");
c.createAlias("profil.profiles", "supProfil");
c.add(Restrictions.eq("profil.id", 4);
c.setProjection(Projections.property("supProfil.id"));
The above should, AFAIK, make an additional join from the join table to the profile table, but it should return the same thing as your SQL query.
thank you very much #JB Nizet
I did actually find the solution yesterday :
hibernateCriteria.createCriteria("profil").createAlias("profiles", "ps").add( Restrictions.eq("ps.id",superieurCriteria.getProfilId()) ) ;
peace.

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>

NHibernate won't delete orphaned object

I have a few classes that look like this
public class Token
{
public int Id
{
get;
set;
}
public ITokenInstance Instance
{
get;
set;
}
}
public interface ITokenInstance
{
int Id
{
get;
set;
}
Token Token
{
get;
set;
}
}
and mapping files
<class name="Token" >
<id name="Id" >
<generator class="hilo" />
</id>
<any name="Instance" meta-type="class" id-type="Int32" cascade="all-delete-orphan">
<column name="instance_type" />
<column name="instance_id" />
</any>
</class>
<class name="TokenInstanceOne" >
<id name="Id" >
<generator class="hilo" />
</id>
<many-to-one name="Token" class="Token" column="token_id"/>
</class>
I have various implementations of the ITokenInstance interface, all looking in different tables but all using the same baisc structure as shown in the mapping. The problem is that whilst i can add a new ITokenInstance to a Token that has no instance set (null) and it will update correctly I can NOT add a new Instance to a Token that has already got an instance and then Update it, NHibernate will add the new instance i provide but not delete the now un-assigned instance. For example
Token token = Session.Get<Token>(4);
var instance = Session.Get<TokenInstanceOne>(1);
Assert.AreSame(token.Instance, instance);
var newInstance = new TokenInstanceOne();
token.Instance = newInstance;
newInstance.Token = token;
instance.Token = null;
Session.Flush();
This fires SQL to insert the new TokenInstance, and updates the token table to point at it, it does NOT delete the instance that was originaly set to the token. Does anyone know how I can instruct NHibernate to delete the original TokenInstance from the database
EIDT:
I had missed something off that is now included in the code example (setting original TokenInstance's Token reference to null).
Also just to clarify this is the SQL NHibernate is producing;
INSERT INTO TokenInstanceOne (token_id, Id) VALUES (#p0, #p1); #p0 = '4', #p1 = '32768'
UPDATE Token SET instance_type = #p0, instance_id = #p1 WHERE Id = #p2; #p0 = 'ClassLibrary1.TokenInstanceOne', #p1 = '32768', #p2 = '4'
UPDATE TokenInstanceOne SET token_id = #p0 WHERE Id = #p1; #p0 = '', #p1 = '1'
Notice the last Update is setting token_id = '', what i need is for NHibernate to delete the row instead.
NHibernate does not implement a so called persistent garbage collection. There are situations where you need to remove entities explicitly. The cascade is for the case when you delete the Token.
This is your code:
var token = Session.Get<Token>(4);
Assert.IsNotNull(token.Instance);
// remove the old token
Session.Delete(token.Instance);
// assign the new token
var newInstance = new TokenInstance();
token.Instance = newInstance;
newInstance.Token = token;
// don't need to call update, the token is in the session.
// (except you turned off session flush)
// Session.Update(token);
Sorry, I misunderstood your question.
Have you tried setting inverse="true" on your any end?
Alternatively move the cascade to th the other class' mapping.
Read

Named queries with nHibernate

I am having a great deal of trouble getting named queries to work with nHibernate. My latest problem is getting the error message "could not execute query" with no additional information. Are there any complete examples I can download from somewhere because all the tutorials and documentation examples provide code snippits but only tell half the story about getting it to work.
Here is the code that is giving me problems.
Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Model.Entities
{
public class TableInfo
{
public string TABLENAME { get; set; }
public string COLUMNNAME { get; set; }
#region Overrides
public override int GetHashCode()
{
int result = TABLENAME.GetHashCode();
result += COLUMNNAME.GetHashCode();
return result;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
TableInfo dict = (TableInfo)obj;
return
dict.TABLENAME.IsEqual(this.TABLENAME) &&
dict.COLUMNNAME.IsEqual(this.COLUMNNAME);
}
#endregion
}
}
Mapping File
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model.Entities" assembly="Model" default-lazy="false">
<class name="Model.Entities.TableInfo, Model" table="UIM_TableColumnInfo">
<composite-id>
<key-property name="TABLENAME" column="TABLENAME" type="string"></key-property>
<key-property name="COLUMNNAME" column="COLUMNNAME" type="string"></key-property>
</composite-id>
</class>
<sql-query name="GetTableInfo">
<return alias="tableInfo" class="Model.Entities.TableInfo, Model">
<return-property name="TABLENAME" column="TABLENAME"/>
<return-property name="COLUMNNAME" column="COLUMNNAME"/>
</return>
<![CDATA[
select
info.tci_table_name TABLENAME
, info.tci_column_name COLUMNNAME
from ALL_TAB_COLS c
,( select 'DATE' TYPE_NAME, 'D' data_type_ind from dual
union select 'NUMBER','N' from dual
union select 'VARCHAR2','S' from dual
) ct
, UIM_TableColumnInfo info
where c.DATA_TYPE = ct.TYPE_NAME (+)
and c.column_id is not null
and UPPER(c.TABLE_NAME) = :TableName
and UPPER(c.COLUMN_NAME) = UPPER(info.tci_column_name (+))
order by c.column_id
]]>
</sql-query>
</hibernate-mapping>
Calling Code
public List<TableInfo> GetTableInfo(string tableName)
{
return m_TableInfoRepository
.NamedQuery("GetTableInfo")
.SetString("TableName", tableName)
.List<TableInfo>() as List<TableInfo>;
}
I assume that you have tested before the SQL in your client database, so I think that maybe we should see what is happening inside, so I can recommend you this links;
Named Query Error
Using NHibernate and Log4Net in ASP.NET 2.0 applications
How do I view the SQL that is generated by nHibernate?
Hope it helps.
The inner exception should provide the actual sql that was generated and tried to run. Paste this into a database query and run it directly in the database. This will help guide you. It will be a lot easier once you know why the SQL could not be executed
Maybe I'm wrong but it seems that could be a conflict between the table "TABLENAME" and the parameter ":TableName", what happens if you try to use another parameter name?