java with ibatis : does ibatis support constructor with arguments

hi guys

Is it a MUST that my resultClass have a no -arg constructor ?

 I am using Spring with Ibatis. This is code i have so far.


I have in my xml file

------------------------------------------
<typeAlias alias ="userInfo" type ="nj.ado.UserInformation"/>

<select id ="my.query" resultClass="userInfo" parameterclass="java.lang.String">
select A.username,A.Id from User A where A.username= #username:CHAR#
</select>
-------------------------------------------


This is my UserInformation.java

----------------------------------------
public class UserInformation extends org.springframework.security.userdetails.User
{
public String accountId = null;
public UserInformation(String username,String password,boolean enabled,GrantedAuthority[]
  authorities, String accountId) throws IllegalArgumentException
        {
        super(username,password,enabled,authorities); // calls superclass constructor
        this.accountId = accountId;
        }
setAccountId();
getAccountId();
}
-------------------------------------

This is how i am calling the query
----------------------------------------------
UserInformation ui = (UserInformation)SqlMapClientTemplate.queryForObject("my.query" , username);
------------------------------------------------

pretty straightforward.

AND this is the error i get
>>>> 
InstantiationException. UserInformation canot be instantiated

I am assuming it is because i dont have a no argument constructor in UserInformation.java ? Is that the problem?

PS: I cannot have a no argument constructor in UserInformation.java because spring doesnt allow me to do that.

Any help would be appreciated.

thanks.
royjaydAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
>>I am assuming it is because i dont have a no argument constructor in UserInformation.java ? Is that the problem?

Probably. Generally speaking, for greatest flexibility, java classes should be bean-compliant

>>PS: I cannot have a no argument constructor in UserInformation.java because spring doesnt allow me to do that.

What makes you say that?
royjaydAuthor Commented:
>>>What makes you say that?
because i tried doing the following

i added another second constructor like this

public class UserInformation extends org.springframework.security.userdetails.User
{
public String accountId = null;
public UserInformation(String username,String password,boolean enabled,GrantedAuthority[]
  authorities, String accountId) throws IllegalArgumentException
        {
        super(username,password,enabled,authorities); // calls superclass constructor
        this.accountId = accountId;
        }

public UserInformation() //second constructor ..ERROR :Must Explicitly invoke another constructor

setAccountId();
getAccountId();
}


Is there a solution to this problem so that my ibatis works?

thanks
CEHJCommented:
You can do the following
public UserInformation() { 
	    super("", "", false, null);
            // Now set fields to proper values
	}

Open in new window

Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

royjaydAuthor Commented:
you mean have that as the second constructor,right?
so the constructor with arguments will be used by spring and constructor without arguments will be used by ibatis?
CEHJCommented:
Anything requiring a no-args one will use that one
royjaydAuthor Commented:
>>Now set fields to proper values

but how do i do that? for instance how do i set the
username,password,enabled,authorities and accountId fields?

PS : username,password,enabled,authorities fields are defined in the super class User.

thx
CEHJCommented:
Sorry - you're right. The superclass is immutable effectively. You should probably use your own implementation of the UserDetails interface, giving it a no-arg ctor
royjaydAuthor Commented:
>>>You should probably use your own implementation of the UserDetails interface, giving it a no-arg ctor
UserDetails Interface? or User class ?

how? can you provide code to do that plz.
royjaydAuthor Commented:
just to avoid any confusion

I am using Springs  org.springframework.security.userdetails.User class
This User class internally impliments org.springframework.security.userdetails.UserDetails
So my object structure is
public class UserInformation extends org.springframework.security.userdetails.User
//my custom fields

CEHJCommented:
>>how? can you provide code to do that plz.

Add the requisite methods to the below:
public class UserInformation implements UserDetails {
    public UserInformation() {}
}

Open in new window

royjaydAuthor Commented:
>>>>Add the requisite methods to the below:

Can you be a little more descriptive?
How can i add username, password, ect from the User class in UserInformation ?
I cant!

thanks.
CEHJCommented:
>>How can i add username, password, ect from the User class in UserInformation ?

You wouldn't have a User class - you'd be making your own
royjaydAuthor Commented:
oh ok. thats a new design strategy. i really need to use (or Re-use) User class

thx
CEHJCommented:
Try then simply *using* the User class. You could try using a <constructor> element in a <resultMap> in IBatis

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
royjaydAuthor Commented:
>>>You wouldn't have a User class - you'd be making your own
ok i am going with this approach. This is what i have
public class UserInformation implements org.springframework.security.userdetails.UserDetails

      public UserInformation () {}
      
      public String username = null;
      public String password = null;      
      public String accountId = null;  
      public String email = null;
      public String firstName = null;
      public String lastName = null;
      public boolean accountStatus;
      public boolean enabled;
      public GrantedAuthority[] authorities = null;
set() for all above fields
get() for all above fields

So will the username (in this class) override the username in User class?

thx
royjaydAuthor Commented:
For some reason it doesnt work

I am using the UserInformation class above like this

               UserInformation userInfo = null;  
              GrantedAuthority[] authorities = null;      
                 try{
                SqlMapClientTemplate sqlsecuritytemplate = getSqlTemplate();
                 //calling IBATIs sucessfully
                userInfo = (CopyOfUserInformation)sqlsecuritytemplate.queryForObject(SELECT_USERINFO,username);  

  'userInfo' object contains valid username,password, ect but the user still doesnt have access.

PS: if i use the earlier approach of extending User class and passing parametres in User class constructor it works fine.

What am i doing wrong?
royjaydAuthor Commented:
cehj(or anyone else), can you please help me out with this? I am getting some pressure from my teamlead on this issue. thanks
CEHJCommented:
Try comparing your implementation with their source
royjaydAuthor Commented:
>>>with their source

where can i find their source? sorry if it is a dumb question
royjaydAuthor Commented:
>>>>Try comparing your implementation with their source

what exactly do i compare?

This is my UserInformation class (equavalant of User class)

1.
public class UserInformation implements org.springframework.security.userdetails.UserDetails

      public UserInformation () {}
     
      public String username = null;
      public String password = null;      
      public String accountId = null;  
      public String email = null;
      public String firstName = null;
      public String lastName = null;
      public boolean accountStatus;
      public boolean enabled;
      public GrantedAuthority[] authorities = null;
set() for all above fields
get() for all above fields

and

2. i am sucessfully using IBATIS to retrieve the username, pasword and authorities like this
SqlMapClientTemplate sqlsecuritytemplate = getSqlTemplate();
                //calling IBATIs sucessfully
userInfo = (UserInformation)sqlsecuritytemplate.queryForObject(my_query, username);  

but it doesnt work.

CEHJCommented:
If your implementation is doing everything that their class is doing, then the problem is likely to be with Ibatis
royjaydAuthor Commented:
i think the problem is in the working code (plain jdbc), i am invoking the constructor of the USER class and passing the username,password,enabled,authorities (by using super(..)

public UserInformation(String username,String password,boolean enabled,GrantedAuthority[]
  authorities, String accountId) throws IllegalArgumentException
        {
        super(username,password,enabled,authorities); // calls superclass constructor
        this.accountId = accountId;
        }

but When using IBATIS i am not invoking the USER class constructor and that is causing the problem
i think..
royjaydAuthor Commented:
>>>You could try using a <constructor> element in a <resultMap> in IBatis

Can you tell me how i can do that?
This is my ibatis file
<typeAlias alias ="userInfo" type ="nj.ado.UserInformation"/>

<select id ="my.query" resultClass="userInfo" parameterclass="java.lang.String">
select A.username,A.Id from User A where A.username= #username:CHAR#
</select>

How do i add <constructor> element in a <resultMap>?

My constructor signature in UserInformation class  is

public UserInformation(String username,String password,boolean enabled,GrantedAuthority[]
  authorities, String accountId) throws IllegalArgumentException
        {
        super(username,password,enabled,authorities); // calls superclass constructor of USER class
        this.accountId = accountId;
        }


any help will be greatly appreciated

thanks
CEHJCommented:
Actually, i think the <constructor> element should be able to handle that, and this is covered in the user guide. Unfortunately i haven't used spring and ibatis together
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.