Letractively / mandubian-play-crud-siena

Automatically exported from code.google.com/p/mandubian-play-crud-siena
0 stars 0 forks source link

Embedded items aren't saved #1

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a model with an @EmbeddedList. The @Embedded object has a relation 
element (a reference to another model)
2. Use SienaCRUD to edit the model. Add one element to the list and edit the 
value.
3. Save the object

What is the expected output? What do you see instead?
The embedded object should be saved, It isn't.

What version of the product are you using? On what operating system?
Siena CRUD 1.2 with Play 1.1

Original issue reported on code.google.com by araco...@gmail.com on 5 Dec 2010 at 11:41

GoogleCodeExporter commented 8 years ago
Can you try something please?
1. Create a model with an @EmbeddedList. The @Embedded object has a relation 
element (a reference to another model)
2. Use SienaCRUD to edit the model. DON'T ADD AN ELEMENT TO THE LIST
3. Save
4. Come back to your object and NOW ADD AN ELEMENT TO THE LIST
5. Save

Is your element saved?
If yes, this is a limitation I know but this workaround can help you ;)

Thanks
Pascal

Original comment by pascal.v...@gmail.com on 7 Dec 2010 at 8:18

GoogleCodeExporter commented 8 years ago
Hi,

sorry, I did not explain myself properly :) The issue is that the relation 
defined inside the @Embedded object is not saved.

That is, if I add 5 elements to the list in a row, each element will display a 
dropdown with the possible options for the rel. 

If I select 5 values for the 5 rels and save, the object will keep 5 elements 
in the list, but their relations will not be stored, so the dropdowns will 
display the default value "none" instead of the one I selected.

This happens either if the object is new or was saved before.

Best regards,
Pere Villega

Original comment by araco...@gmail.com on 7 Dec 2010 at 8:26

GoogleCodeExporter commented 8 years ago
I'm sorry but I'm really not sure to understand :)
Can you give an example of your models code with the relation and the @embedded?
Like that I can test it by myself :)

thks
Pascal

Original comment by pascal.v...@gmail.com on 7 Dec 2010 at 10:33

GoogleCodeExporter commented 8 years ago
Yes, an example will be better:

public class Item extends extends SienaSupport {

        @Id(Generator.AUTO_INCREMENT)
        public Long id;

        @Column("name")
        @Max(100) @NotNull
        public String name;
}

public class User extends extends SienaSupport {

        @Id(Generator.AUTO_INCREMENT)
        public Long id;

        @Column("first_name")
        @Max(100) @NotNull
        public String firstName;        

        @Embedded
        public List<UserItem> items;
}

@EmbeddedList
public class UserItem {
  @At(0) @Column("myitems") public Item item;
}

The embedded list doesn't work properly, I can't store references to Item from 
the user. I can't use it via an 1:M relation due to business rules (it's a M:M 
relation but can't be navigated from one side).

Original comment by araco...@gmail.com on 7 Dec 2010 at 11:09

GoogleCodeExporter commented 8 years ago
just a question: do you use siena-jdbc or anything else? 
I use GAE currently and apparently, the bug is even worse :)...
I'm going to investigate: thank for testing this because I think I forgot to 
test it simply!

regards
Pascal

Original comment by pascal.v...@gmail.com on 8 Dec 2010 at 8:20

GoogleCodeExporter commented 8 years ago
Siena with GAE yes :) (AFAIK is the only way it works with Play, isn't it?)

You are welcome!

Original comment by araco...@gmail.com on 8 Dec 2010 at 8:24

GoogleCodeExporter commented 8 years ago
yes you're right, Siena+Play works only with GAE :)
Another question: with the code above, when I click on "Add an element" on the 
list "items", I get an exception concerning a missing @At annotation. 
Apparently you don't get that. Can you confirm?

Original comment by pascal.v...@gmail.com on 8 Dec 2010 at 9:40

GoogleCodeExporter commented 8 years ago
Hi,

I remove that part so I don't have it now, but afaik the @At(0) worked fine... 
I copied from the sample posted here :)

Original comment by araco...@gmail.com on 8 Dec 2010 at 7:52

GoogleCodeExporter commented 8 years ago
I discovered my problem: it is linked to the fact that I define my embedded 
classes as inner classes. There is a problem with inner classes json list 
serialization in Siena. I'm going to investigate this and then go on your bug ;)
regards
Pascal

Original comment by pascal.v...@gmail.com on 10 Dec 2010 at 2:19

GoogleCodeExporter commented 8 years ago
ok great :)

Original comment by araco...@gmail.com on 10 Dec 2010 at 6:38

GoogleCodeExporter commented 8 years ago
I have corrected my bug with inner classes in embedded lists...
Anyway, I have studied your problem and it's true, it is not managed by 
crudsiena neither siena itself. Basically, Siena serializes embedded entities 
into JSON but it refuses to serialize complex types found in embedded classes.
In fact, embedded entities are useful to store valued entities instead of an 
external key. In this way, you don't have to make complex join requests (which 
are not available in NoSQL DBs anyway).
As a consequence, I'm not sure it is very good to store an id of an external 
entity in an embedded entity as you do because you re-create this foreign 
constraint that @embedded removes.
But I try to understand your exact need to see if another way wouldn't be 
better.
So now, what do you need exactly? Do you want to store the id of the external 
entity or do you want to store one value of a field in this external entity or 
maybe even several values of fields in this external entity?

Does something like the following could fit your need?
public class User extends extends SienaSupport {        
        @Id(Generator.AUTO_INCREMENT)
        public Long id;

        @Embedded
        public List<UserItem> items;

        @EmbeddedList
        public class UserItem {
                @At(0) @Selector(table="users", column="mycolumn") public String myvalue;
                @At(0) @Selector(table="users", columns="mycolumn1, mycolumn2") public Json myvalues;
        }

}

@Selector(table="users", column="mycolumn") means the string value should be 
selected from the entities in table "users" and column "mycolumn" (the 
crudsiena would manage the annotation @Selector but not siena)

@Selector(table="users", columns="mycolumn1, mycolumn2") means the Json value 
is build as a map for example whose values are extracted from the entities in 
table "users" and columns "mycolumn1" and "mycolumn2"

regards
Pascal

Original comment by pascal.v...@gmail.com on 11 Dec 2010 at 5:53

GoogleCodeExporter commented 8 years ago
Hi,

thanks for the fix :) The issue is that I have, on many places of the 
application, M:M relations. These relations can only be navigated from one side 
(that is, A object can get all the B objects related to it, but B must not know 
of any A related to it).

As they are existing objects and they may be modified, I need a reference to be 
able to easily access its properties and methods. 

I thought on storing this relation as a embedded list, but I found the 
aforementioned issues. Right know we have a bit of a blocker, if Siena doesn't 
allow that maybe we will have to change ORM :(

Thanks for your efforts!

Original comment by araco...@gmail.com on 12 Dec 2010 at 11:05

GoogleCodeExporter commented 8 years ago
Be careful, you are using GAE...
it is not a relational DB so you can't create models as in a relational DB. You 
can't join for example so your model can't the same as a relational model. Even 
if you change ORM, you will have the same design problems. For example when 
using Datanucleus JDO/JPA, you quickly become aware that you are exactly using 
JDO/JPA but just a facade with JDO/JPA syntax.

With your one way relation, it seems the embedded objects are not a bad choice. 
But if you want to store a backward reference to its parent in the embedded 
object, you should store its ID simply as a long and manage the corresponding 
entity retrieval manually.
You can't ask Siena to perform that for you because: as there are no join, it 
would mean performing lots of hidden Model.fetch() which may consume huge 
computation time.

Don't hesitate to ask me if you have other questions.

regards
Pascal

Original comment by pascal.v...@gmail.com on 12 Dec 2010 at 11:27

GoogleCodeExporter commented 8 years ago
Hi, thanks for the advice. We will check what can we do :)

Best regards,
Pere Villega

Original comment by araco...@gmail.com on 12 Dec 2010 at 11:29