google-code-export / twig-persist

Automatically exported from code.google.com/p/twig-persist
1 stars 1 forks source link

controlling Activation on twig 2 #72

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hello,

In the attached maven project I have a datamodel composed of three classes : 
Band, Album, Song.

An album has a list of songs and it belongs to a band.

I have added the following annotations without success :

    @Activate(0)private Band band; // we do not want the band to be activated
    @Activate private List<Song> songs; // we want the songs to be activtated

What steps will reproduce the problem?
1. download the attached maven (maven 3) project
2. run the DaoTest : 'mvn test -Dtest=DaoTest'

What is the expected output? What do you see instead?
assertNotNull(blackAlbum.getSongs()) and assertNull(blackAlbum.getBand()) 
should succeed

What version of the product are you using? On what operating system?
twig version : 2.0-beta4
OS : macos

regards

vincent

Original issue reported on code.google.com by helmetc...@gmail.com on 7 Sep 2011 at 12:30

Attachments:

GoogleCodeExporter commented 9 years ago
I have not yet set up and run your project.  But looking at your description I 
can see that assertNull(blackAlbum.getBand()) should not succeed.  Instead, 
there should be an unactivated instance there.

When the current activation depth is 0, as it will be for the band field, no 
Entity is fetched from the datastore.  BUT, we do have the Key for the band 
entity and use it to create an unactivated instance that only has the @Id and 
@Parent fields set.

When you activate the band instance, Twig looks up the datastore Key (using the 
instance as a key in the Map<Object, Key>) and sends a get() request to the 
datastore for the rest of the data.

Original comment by jdpatterson on 8 Sep 2011 at 3:11

GoogleCodeExporter commented 9 years ago
Also, can you try with the latest source

http://code.google.com/p/twig-persist/wiki/Integration2_0

Original comment by jdpatterson on 8 Sep 2011 at 3:13

GoogleCodeExporter commented 9 years ago
Hi, and thank you for your help

I have added a 'description' attribute to the Band class and switch to 
2.0-SNAPSHOT.

(see attached project)

The following tests still fail :

// check that the album songs is loaded thanks to '@Activate' 
assertNotNull(blackAlbum.getSongs());

// check that the album band is NOT loaded thanks to '@Activate(0)'
assertNull(blackAlbum.getBand().getDescription());

I am pretty sure I am missing something, but I cannot see what.

Original comment by helmetc...@gmail.com on 8 Sep 2011 at 2:39

Attachments:

GoogleCodeExporter commented 9 years ago
does anyone have an idea ?

Original comment by helmetc...@gmail.com on 13 Sep 2011 at 9:22

GoogleCodeExporter commented 9 years ago
I can see that you are using one ObjectDatastore to both store and then 
retrieve the instances.  One of Twigs guarantees is that an Entity will only be 
represented by one instance in memory.  Therefore the instance that is returned 
from your load() command is identical (==) the instance you stored (with 
description).

If you want to break this behaviour (only normally useful for test) you can 
either use different OBjectDatastore's or call 
ObjectDatastore.disassociateAll() on the shared one.

Original comment by jdpatterson on 13 Sep 2011 at 9:41

GoogleCodeExporter commented 9 years ago
Marking as invalid because its working as expected.  Reopen this if I missed 
something.

Original comment by jdpatterson on 13 Sep 2011 at 9:42

GoogleCodeExporter commented 9 years ago
I have slightly changed the code so that we now have a singleton of 
AnnotationObjectDatastore (see TwigDatastoreSingleton.java in the new zip) 
instead of creating a new instance everytime we instantiate a Dao.

Also, in DaoTest after the creation of sample sample data I call diassociateAll.

 this.storeSampleData();        
 TwigDatastoreSingleton.getSingletonObject().disassociateAll();

So now, we should have brand new loaded objects with their attributes activated 
as defined by the annotations. 

But still the two tests fail.

  // check that the album songs is loaded thanks to '@Activate' 
  assertNotNull(blackAlbum.getSongs());
  // check that the album band is NOT loaded thanks to '@Activate(0)'
  assertNull(blackAlbum.getBand().getDescription());

Original comment by helmetc...@gmail.com on 15 Sep 2011 at 1:15

Attachments:

GoogleCodeExporter commented 9 years ago
Do these tests fail when you do not reuse the OD?  It is not designed to be 
reused - in fact if you run it in multi threaded mode an exception will be 
thrown to warn you if you try.

An OD is single threaded because it has internal state that will be left 
inconsistent if (when) an exception is thrown. 

Original comment by jdpatterson on 16 Sep 2011 at 10:23

GoogleCodeExporter commented 9 years ago
close !

I have abandoned the OD singleton (i.e. one OD is created every time we 
instantiate a Dao)

and now '@Activate(0)' on Album.band works :

  // check that the album band is NOT loaded thanks to '@Activate(0)'
  assertNull(blackAlbum.getBand().getDescription());
  albumDao_bis.refresh(blackAlbum.getBand());
  // check that the band description gets loaded if we refresh the band
  assertNotNull(blackAlbum.getBand().getDescription());

I still have a problem with Album.songs though :
  // check that the album songs is loaded thanks to '@Activate' 
  assertNotNull(blackAlbum.getSongs());
  assertNotNull(blackAlbum.getSongs().size()>0);

What is really even weirder is that "assertNotNull(blackAlbum.getSongs())" 
fails even when intializing the list in the Album class :

@Activate private List<Song> songs = new ArrayList<Song>()

I have attached last version of the project

Original comment by helmetc...@gmail.com on 16 Sep 2011 at 1:05

Attachments:

GoogleCodeExporter commented 9 years ago
I have not run and debugged your sample app - sorry, very busy and it is just 
too time consuming to debug projects and figure out how you are setting things 
up.

Keep in mind that the activation ideas you are using are shown working in 
simple unit tests that come with the project.  If you destill your problem to a 
simple all-in-one unit test then I will be able to debug it.

Tips: If an instance is loaded and not activated then even if it has a field 
with @Activate that field will not be loaded - the entire object is simply not 
processed.

An instance could be loaded unactivated if it is referenced by another 
instance.  You will then need to activate it manually.

Original comment by jdpatterson on 16 Sep 2011 at 1:36

GoogleCodeExporter commented 9 years ago
Also, your last assert statement is invalid:

assertNotNull(blackAlbum.getSongs().size()>0)

Original comment by jdpatterson on 16 Sep 2011 at 1:43