Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
ResultMaps : Injecting collection without having any getter
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  14 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Frédéric Camblor  
View profile  
 More options Oct 13 2012, 7:50 am
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Sat, 13 Oct 2012 13:50:29 +0200
Local: Sat, Oct 13 2012 7:50 am
Subject: ResultMaps : Injecting collection without having any getter

Hi folks !

I have a relatively simple case, something like this :

public class Foo {
    private List<Bar> bars;

    public void List<Bar> getBars(){
        return this.bars;
    }

    // I don't want to provide a Bars setter to the outside of my bean
    // I only want to create bars from quixes I retrieve from db
    public void setQuixes(List<Quix> quixes){
        this.bars = convertQuixesToBars(quixes);
    }

    private List<Bar> convertQuixesToBars(List<Quix> quixes){ ... }

}

In my mapping file, I'll have something like this :
<resultMap id="Quix" type="foo.Quix">....</resultMap>
<resultMap id="Foo" type="foo.Foo">
    <collection property="quixes" resultMap="Quix" columnPrefix="quixes." />
</resultMap>

When mapping occurs, I catch an exception :
*There is no getter for property named 'quixes' in 'class foo.Foo*

Seems like MyBatis needs a collection getter in order, I suppose, to
successively call add() on it.
I was just wondering : would there be a way to tell Mybatis to create the
collection "externally" and the inject it via the setter method only
(without calling the getQuixes() any time) ?

Thanks in advance,

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 17 2012, 3:22 am
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Wed, 17 Oct 2012 09:22:10 +0200
Local: Wed, Oct 17 2012 3:22 am
Subject: Re: ResultMaps : Injecting collection without having any getter

No advice about this topic ?

FTM, I only found 2 workarounds :

   - Creating a new DAO-layer-dedicated POJO having a List<Quix> inside it,
   and converting it to my Foo instance after db retrieval.
   Why not but heh, you know it's kinda boring to not forget to make this
   POJO evolve every time Foo evolves.

   - Creating an ugly Foo subclass having an anonymous ArrayList<Quix>
   subclass having the add() method overriden which populate the List<Bar> on
   every add.
   Note that I _had_ to instantiate this ArrayList in the constructor and
   never instantiate it after because MyBatis seems to act "externally" with
   collections, like this :
   *Foo createdFoo = new Foo();
   **List<Quix> quixes = ....
   createdFoo.setQuixes(quixes);
   createdFoo.getQuixes().add(convertRowToQuix());
   createdFoo.getQuixes().add(convertRowToQuix());
   *
   Instead of acting "on its side" like this :
   *Foo createdFoo = new Foo();
   List<Quix> quixes = ....
   quixes.add(convertRowToQuix());
   quixes.add(convertRowToQuix());
   createdFoo.set(quixes);*

Am I wrong ? (I would love to be wrong ! :-))

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

On Sat, Oct 13, 2012 at 1:50 PM, Frédéric Camblor <fcamb...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Poitras Christian  
View profile  
 More options Oct 17 2012, 9:03 am
From: Poitras Christian <Christian.Poit...@ircm.qc.ca>
Date: Wed, 17 Oct 2012 09:03:43 -0400
Local: Wed, Oct 17 2012 9:03 am
Subject: RE: ResultMaps : Injecting collection without having any getter

Hi,

As a workaround, you can add a private getter method.

Christian

De : mybatis-user@googlegroups.com [mailto:mybatis-user@googlegroups.com] De la part de Frédéric Camblor
Envoyé : October-17-12 3:22 AM
Ŕ : mybatis-user@googlegroups.com
Objet : Re: ResultMaps : Injecting collection without having any getter

No advice about this topic ?

FTM, I only found 2 workarounds :

 *   Creating a new DAO-layer-dedicated POJO having a List<Quix> inside it, and converting it to my Foo instance after db retrieval.
Why not but heh, you know it's kinda boring to not forget to make this POJO evolve every time Foo evolves.
 *   Creating an ugly Foo subclass having an anonymous ArrayList<Quix> subclass having the add() method overriden which populate the List<Bar> on every add.
Note that I _had_ to instantiate this ArrayList in the constructor and never instantiate it after because MyBatis seems to act "externally" with collections, like this :
Foo createdFoo = new Foo();
List<Quix> quixes = ....
createdFoo.setQuixes(quixes);
createdFoo.getQuixes().add(convertRowToQuix());
createdFoo.getQuixes().add(convertRowToQuix());

Instead of acting "on its side" like this :
Foo createdFoo = new Foo();
List<Quix> quixes = ....
quixes.add(convertRowToQuix());
quixes.add(convertRowToQuix());
createdFoo.set(quixes);

Am I wrong ? (I would love to be wrong ! :-))

Frédéric Camblor [cid:~WRD000.jpg] <http://fcamblor.wordpress.com/>  [cid:~WRD000.jpg] <http://www.twitter.com/fcamblor>
Bordeaux JUG<http://bordeauxjug.org/> Board member
Jenkins<http://jenkins-ci.org/> community member & plugin commiter

On Sat, Oct 13, 2012 at 1:50 PM, Frédéric Camblor <fcamb...@gmail.com<mailto:fcamb...@gmail.com>> wrote:
Hi folks !

I have a relatively simple case, something like this :

public class Foo {
    private List<Bar> bars;

    public void List<Bar> getBars(){
        return this.bars;
    }

    // I don't want to provide a Bars setter to the outside of my bean
    // I only want to create bars from quixes I retrieve from db
    public void setQuixes(List<Quix> quixes){
        this.bars = convertQuixesToBars(quixes);
    }

    private List<Bar> convertQuixesToBars(List<Quix> quixes){ ... }

}

In my mapping file, I'll have something like this :
<resultMap id="Quix" type="foo.Quix">....</resultMap>
<resultMap id="Foo" type="foo.Foo">
    <collection property="quixes" resultMap="Quix" columnPrefix="quixes." />
</resultMap>

When mapping occurs, I catch an exception :
There is no getter for property named 'quixes' in 'class foo.Foo

Seems like MyBatis needs a collection getter in order, I suppose, to successively call add() on it.
I was just wondering : would there be a way to tell Mybatis to create the collection "externally" and the inject it via the setter method only (without calling the getQuixes() any time) ?

Thanks in advance,

Frédéric Camblor [cid:~WRD000.jpg] <http://fcamblor.wordpress.com/>  [cid:~WRD000.jpg] <http://www.twitter.com/fcamblor>
Bordeaux JUG<http://bordeauxjug.org/> Board member
Jenkins<http://jenkins-ci.org/> community member & plugin commiter

  ~WRD000.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Poitras Christian  
View profile  
 More options Oct 17 2012, 9:08 am
From: Poitras Christian <Christian.Poit...@ircm.qc.ca>
Date: Wed, 17 Oct 2012 09:08:04 -0400
Local: Wed, Oct 17 2012 9:08 am
Subject: RE: ResultMaps : Injecting collection without having any getter

Actually MyBatis can use any private getter/setter.
MyBatis can also handle fields (even private) that have no getter/setter, POJOs for example.

Christian

De : mybatis-user@googlegroups.com [mailto:mybatis-user@googlegroups.com] De la part de Poitras Christian
Envoyé : October-17-12 9:04 AM
Ŕ : 'mybatis-user@googlegroups.com'
Objet : RE: ResultMaps : Injecting collection without having any getter

Hi,

As a workaround, you can add a private getter method.

Christian

De : mybatis-user@googlegroups.com<mailto:mybatis-user@googlegroups.com> [mailto:mybatis-user@googlegroups.com] De la part de Frédéric Camblor
Envoyé : October-17-12 3:22 AM
Ŕ : mybatis-user@googlegroups.com<mailto:mybatis-user@googlegroups.com>
Objet : Re: ResultMaps : Injecting collection without having any getter

No advice about this topic ?

FTM, I only found 2 workarounds :

 *   Creating a new DAO-layer-dedicated POJO having a List<Quix> inside it, and converting it to my Foo instance after db retrieval.
Why not but heh, you know it's kinda boring to not forget to make this POJO evolve every time Foo evolves.
 *   Creating an ugly Foo subclass having an anonymous ArrayList<Quix> subclass having the add() method overriden which populate the List<Bar> on every add.
Note that I _had_ to instantiate this ArrayList in the constructor and never instantiate it after because MyBatis seems to act "externally" with collections, like this :
Foo createdFoo = new Foo();
List<Quix> quixes = ....
createdFoo.setQuixes(quixes);
createdFoo.getQuixes().add(convertRowToQuix());
createdFoo.getQuixes().add(convertRowToQuix());

Instead of acting "on its side" like this :
Foo createdFoo = new Foo();
List<Quix> quixes = ....
quixes.add(convertRowToQuix());
quixes.add(convertRowToQuix());
createdFoo.set(quixes);

Am I wrong ? (I would love to be wrong ! :-))

Frédéric Camblor [cid:image001....@01CDAC46.E9F88940] <http://fcamblor.wordpress.com/>  [cid:image001....@01CDAC46.E9F88940] <http://www.twitter.com/fcamblor>
Bordeaux JUG<http://bordeauxjug.org/> Board member
Jenkins<http://jenkins-ci.org/> community member & plugin commiter

On Sat, Oct 13, 2012 at 1:50 PM, Frédéric Camblor <fcamb...@gmail.com<mailto:fcamb...@gmail.com>> wrote:
Hi folks !

I have a relatively simple case, something like this :

public class Foo {
    private List<Bar> bars;

    public void List<Bar> getBars(){
        return this.bars;
    }

    // I don't want to provide a Bars setter to the outside of my bean
    // I only want to create bars from quixes I retrieve from db
    public void setQuixes(List<Quix> quixes){
        this.bars = convertQuixesToBars(quixes);
    }

    private List<Bar> convertQuixesToBars(List<Quix> quixes){ ... }

}

In my mapping file, I'll have something like this :
<resultMap id="Quix" type="foo.Quix">....</resultMap>
<resultMap id="Foo" type="foo.Foo">
    <collection property="quixes" resultMap="Quix" columnPrefix="quixes." />
</resultMap>

When mapping occurs, I catch an exception :
There is no getter for property named 'quixes' in 'class foo.Foo

Seems like MyBatis needs a collection getter in order, I suppose, to successively call add() on it.
I was just wondering : would there be a way to tell Mybatis to create the collection "externally" and the inject it via the setter method only (without calling the getQuixes() any time) ?

Thanks in advance,

Frédéric Camblor [cid:image001....@01CDAC46.E9F88940] <http://fcamblor.wordpress.com/>  [cid:image001....@01CDAC46.E9F88940] <http://www.twitter.com/fcamblor>
Bordeaux JUG<http://bordeauxjug.org/> Board member
Jenkins<http://jenkins-ci.org/> community member & plugin commiter

  image001.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 17 2012, 5:00 pm
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Wed, 17 Oct 2012 23:00:30 +0200
Local: Wed, Oct 17 2012 5:00 pm
Subject: Re: ResultMaps : Injecting collection without having any getter

Yup I already tried adding a private getter.

Problem is, as I said in my previous example, it _seems_ that setter is
only used to inject an empty collection, getter is then called to add()
rows on this collection.
=> Going this way, setter won't have the collection filled completely (so I
cannot fill my List<Bar> field in the setter).

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

On Wed, Oct 17, 2012 at 3:08 PM, Poitras Christian <

  image001.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeff Butler  
View profile  
 More options Oct 17 2012, 5:40 pm
From: Jeff Butler <jeffgbut...@gmail.com>
Date: Wed, 17 Oct 2012 17:40:20 -0400
Local: Wed, Oct 17 2012 5:40 pm
Subject: Re: ResultMaps : Injecting collection without having any getter

That's correct.  This is the way MyBatis works - it processes the result
set row by row and does not build any "side" collections.

We've always said that the best way to keep out of trouble is to make your
MyBatis objects very simple POJOs - as simple as possible.  This can,
unfortunately, lead to an AnemicDomainModel antipattern, but it is the way
MyBatis works and it would be difficult to change.

If you want a rich model, it is best to have some kind of translate layer
between MyBatis POJOs and your rich model.

Jeff Butler

On Wed, Oct 17, 2012 at 5:00 PM, Frédéric Camblor <fcamb...@gmail.com>wrote:

  image001.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frank Martínez  
View profile  
 More options Oct 17 2012, 5:57 pm
From: Frank Martínez <mnesa...@gmail.com>
Date: Wed, 17 Oct 2012 16:57:52 -0500
Local: Wed, Oct 17 2012 5:57 pm
Subject: Re: ResultMaps : Injecting collection without having any getter

Hi Frédéric,

What about a ResultHandler?

http://code.google.com/p/mybatis/wiki/ResultHandlerExample

--
Frank D. Martínez M.

  image001.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 18 2012, 3:22 am
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Thu, 18 Oct 2012 09:21:57 +0200
Local: Thurs, Oct 18 2012 3:21 am
Subject: Re: ResultMaps : Injecting collection without having any getter

@Jeff Ok I understand completely the anemic domain model way of thinking,
and I agree changing current MyBatis behaviour on Collections would be
harmful (especially for backward compat).
But I don't really catch why "external add" was made instead of building a
side collection and injecting it in the end.
It seems really _unnatural_ behaviour compared to other introspection
oriented frameworks (such as spring, jackson, hibernate and so on...)
I'll live with this thought.

@Frank ResultHandler will surely help to remove my ugly ArrayList.add()
overriding behaviour in my collection, it's a good point.
Nevertheless it won't solve the problem (I'll still have to live with a
mybatis-specific model in that case).

Thanks for answers.

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

  image001.jpg
1K Download

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
bryan hunt  
View profile  
 More options Oct 18 2012, 7:02 am
From: bryan hunt <sentimental.br...@gmail.com>
Date: Thu, 18 Oct 2012 12:02:45 +0100
Local: Thurs, Oct 18 2012 7:02 am
Subject: Re: ResultMaps : Injecting collection without having any getter

"I understand completely the anemic domain model way of thinking".

ROFL. Never thought I'd hear that sound-bite again.

I thought the SpringSource consultancy were about the only people promoting
the Rich Domain Model 'pattern', and that was about 6 years ago. I've seen
it in practice a couple of times, and it's not very pretty.

The thing about spaghetti is - try as you may to slurp it up, in a genteel
manner. There's always that rogue strand which escapes the fork/spoon
combination and ruins a perfectly good shirt.

Anaemic Domain Model, anti-pattern. Hmm, not sure I'd call it an
anti-pattern. Call it logical separation of concern.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 18 2012, 12:00 pm
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Thu, 18 Oct 2012 18:00:31 +0200
Local: Thurs, Oct 18 2012 12:00 pm
Subject: Re: ResultMaps : Injecting collection without having any getter

Uh ? What the point here ?
Where did I speak about anemic domain "anti pattern" ?

I'm using anemic POJO currently but heh, you never had any calculated field
in your anemic POJOs ?

I mean... something like this :
public class AnAnemicPOJO {
    private String field1, field2, field3, field4, ......;
    private List<Foo> foos;
    private Map<String, Foo> foosByName = new HashMap<>();

    /* here a bunch of getters/setters for fieldX and foos */

    // A particular case...
    public void setFoos(List<Foo> foos){
        this.foos.addAll(foos);
        for(Foo f: foos){
            this.foosByName.put(f.getName(), f);
        }
    }

    public Foo getFoo(String name){
        // Will avoid iterating over the complete list which could be very
long in some cases...
        return foosByName.get(name);
    }

}

Don't you call this an anemic model ?
To my POV, this is an anemic model _even if_ there is a bit of code inside
it (but heh, that's not business code... just code to speed things up).

So, if your position is to say that I should have 2 models, duplicating
every "fieldX" fields, in respect to "separation of concerns", I personally
find it overkill and unmaintainable on the long term (because I'll have to
bind every field somewhere, and ensure when I add a new field, I don't miss
to bind it)

But once again, I'll live with it since I love philosophy of MyBatis.

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

On Thu, Oct 18, 2012 at 1:02 PM, bryan hunt <sentimental.br...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dridi Boukelmoune  
View profile  
 More options Oct 18 2012, 12:08 pm
From: Dridi Boukelmoune <dridi.boukelmo...@zenika.com>
Date: Thu, 18 Oct 2012 18:07:32 +0200
Local: Thurs, Oct 18 2012 12:07 pm
Subject: Re: ResultMaps : Injecting collection without having any getter
Hi Frédéric,

Could "package-private" visibility be an acceptable compromise ?

Dridi

--
Dridi Boukelmoune
Développeur/Formateur

GSM : +33 (0)6 17 91 14 23


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 18 2012, 1:00 pm
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Thu, 18 Oct 2012 19:00:21 +0200
Local: Thurs, Oct 18 2012 1:00 pm
Subject: Re: ResultMaps : Injecting collection without having any getter

Hi Dridi,

My problem has nothing to do with visibility (or maybe I don't catch your
point, if so, could you elaborate ?).
Problem is due to collections "injected" by MyBatis : they are *always*
empty when passed to the setter.
MyBatis will fille them _after calling the setter_, by calling
getFoos().add(_internallyMapRowToFoo(currentRow));

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

On Thu, Oct 18, 2012 at 6:07 PM, Dridi Boukelmoune <


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dridi Boukelmoune  
View profile  
 More options Oct 19 2012, 5:12 am
From: Dridi Boukelmoune <dridi.boukelmo...@zenika.com>
Date: Fri, 19 Oct 2012 11:12:31 +0200
Local: Fri, Oct 19 2012 5:12 am
Subject: Re: ResultMaps : Injecting collection without having any getter

You could have a default visibility pair of getter/setter that would
_bypass_ your regular public getter/setter which have logic inside.

///
public List<?> getRegular() {
  // the implementation you seek

}

public void setRegular(List<?>) {
  // the implementation you seek

}

List<?> getShortcut() {
  // return the instance MB will add into

}

void setShortcut(List<?>) {
  // get the instance MB will populate
  // initialize stuff
  // maybe add a decorator to the MB list
}

 ///

If you decorate the list MB will set, you can enhance its behaviour (for
instance update foosByName when an element is added).

You could then _expose the public API as intended_, and have some
"invisible" API that should _only be used by trusted parties_ like MyBatis
and unit tests. A bit boilerplate-ish but feasible.

Dridi

On Thu, Oct 18, 2012 at 7:00 PM, Frédéric Camblor <fcamb...@gmail.com>wrote:

--
Dridi Boukelmoune
Développeur/Formateur

GSM : +33 (0)6 17 91 14 23


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Frédéric Camblor  
View profile  
 More options Oct 19 2012, 8:38 am
From: Frédéric Camblor <fcamb...@gmail.com>
Date: Fri, 19 Oct 2012 14:37:49 +0200
Local: Fri, Oct 19 2012 8:37 am
Subject: Re: ResultMaps : Injecting collection without having any getter

Yup this is exactly what I meant in my second
workaround<https://groups.google.com/d/msg/mybatis-user/myPouCEgF5c/lz1tmXmbM6QJ>
but
I'm not a big fan of subclassing ArrayList to decorate add() methods just
for this (it is what I did but heh, not really proud of it).

Frédéric Camblor  <http://fcamblor.wordpress.com/>
<http://www.twitter.com/fcamblor>
Bordeaux JUG <http://bordeauxjug.org/> Board member
Jenkins <http://jenkins-ci.org/> community member & plugin commiter

On Fri, Oct 19, 2012 at 11:12 AM, Dridi Boukelmoune <


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »