Inserting foreign collection fields with their container

2,922 views
Skip to first unread message

candrews

unread,
May 18, 2011, 12:24:14 PM5/18/11
to ORMLite Users
In terms of the foreign collection example at
http://ormlite.svn.sourceforge.net/viewvc/ormlite/ormlite-jdbc/trunk/src/test/java/com/j256/ormlite/examples/foreignCollection/
I'm attempting to create an account, populate the foreign collection
on it, and then save the account.
---
Account account = new Account("test");

int quantity1 = 2;
int itemNumber1 = 21312;
float price1 = 12.32F;
Order order1 = new Order(account, itemNumber1, price1, quantity1);

account.getOrders().add(order1);

accountDao.create(account);
---
However, this doesn't work as account.getOrders().add(order1); throws
a NullPointerException. This makes sense, as the non-public
Account.orders member has not been set. I figure that Account.order is
set by ORMLite when the account object is inserted, updated, or
refreshed. But for my use case, I don't want to perform any of those
operations first.

To provide a bit more background, I'm using Jackson's object mapper to
convert some json into my models. If Account.orders is a
Collection<Order> instead of a ForeignCollection<Order>, Jackson can
figure that out and make a new concrete Collection<Order>, but it
doesn't know how to make a concrete ForeignCollection<Order>, and even
if it did, I'm not sure ORMLite would correctly persist nested foreign
collections like this. Would it? What can I do to make this work?

/me realizes he should grab the ORMLite source and start submitting
patches... :-)

Gray Watson

unread,
May 18, 2011, 1:43:05 PM5/18/11
to ormlit...@googlegroups.com
On May 18, 2011, at 12:24 PM, candrews wrote:

> In terms of the foreign collection example at
> http://ormlite.svn.sourceforge.net/viewvc/ormlite/ormlite-jdbc/trunk/src/test/java/com/j256/ormlite/examples/foreignCollection/
> I'm attempting to create an account, populate the foreign collection
> on it, and then save the account.

Huh, I had forgotten that ForeignCollection.add() works. Funny. So the issue is that you want to create the collections without doing any database transactions. This would be pretty simple. I'm going to add a getEmptyForeignCollection() or some such to the dao.

Account account = new Account("test");

account.orders = accountDao.getEmptyForeignCollection("orders");

Would that work?

> I figure that Account.order is set by ORMLite when the account object is inserted, updated, or
> refreshed.

Not inserted nor updated. Only query or refresh would create the collection.

> If Account.orders is a Collection<Order> instead of a ForeignCollection<Order>, Jackson can
> figure that out and make a new concrete Collection<Order>

This is supposed to work. ForeignCollection extends Collection so you should be able to say Collection<Order> and under the covers you will get an eager or lazy collection.

gray

candrews

unread,
May 18, 2011, 2:30:28 PM5/18/11
to ORMLite Users
On May 18, 1:43 pm, Gray Watson <256....@gmail.com> wrote:
> On May 18, 2011, at 12:24 PM, candrews wrote:
>
> > In terms of the foreign collection example at
> >http://ormlite.svn.sourceforge.net/viewvc/ormlite/ormlite-jdbc/trunk/...
> > I'm attempting to create an account, populate the foreign collection
> > on it, and then save the account.
>
> Huh, I had forgotten that ForeignCollection.add() works.  Funny.   So the issue is that you want to create the collections without doing any database transactions.  This would be pretty simple.  I'm going to add a getEmptyForeignCollection() or some such to the dao.
>
>         Account account = new Account("test");
>         account.orders = accountDao.getEmptyForeignCollection("orders");
>
> Would that work?

That would almost work for my case (which I don't think is too
unusual). I'd like to make a Jackson deserializer for
ForeignCollection<T> (that extends
org.codehaus.jackson.map.deser.CollectionDeserializer), and that
deserializer would not know which class contains the collection itself
(all it knows is that a deserializer for ForeignCollection<T> has been
requested, it doesn't know it was request as a member of Account).
With that in mind, is it possible to have a concrete class that I
could construct that implements ForeignCollection<T>?

>
> > I figure that Account.order is set by ORMLite when the account object is inserted, updated, or
> > refreshed.
>
> Not inserted nor updated.  Only query or refresh would create the collection.

Logically, it seems like the collection should be created upon insert
or update. Of course, ideally, it seems the collection should be
created when the object is instantiated, I think.

>
> > If Account.orders is a Collection<Order> instead of a ForeignCollection<Order>, Jackson can
> > figure that out and make a new concrete Collection<Order>
>
> This is supposed to work.  ForeignCollection extends Collection so you should be able to say Collection<Order> and under the covers you will get an eager or lazy collection.
>
> gray

The problem is with Jackson's deserialization (when it has to create a
concrete implementation of ForeignCollection<Order>), and it doesn't
know how to do that. For example, List<Order> doesn't extend
ForeignCollection<Order>, so Jackson can't use list. Serialization
already seems to work well for the reason you mentioned.

Gray

unread,
May 22, 2011, 10:04:41 AM5/22/11
to ORMLite Users
Just to close this thread, in 4.22 I added the
Dao.getEmptyForeignCollection(String fieldName) method. Here are the
Javadocs:

http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/dao/Dao.html#getEmptyForeignCollection%28java.lang.String%29

gray

Анна Кочешкова

unread,
Apr 12, 2017, 5:55:11 AM4/12/17
to ORMLite Users
Hello, have encountered the same issue as you. Have you figured out how to create Foreign Collection filed automatically when creating the container (I, too, deserialize the objects from json and want to create them with one statement)?

воскресенье, 22 мая 2011 г., 18:04:41 UTC+4 пользователь Gray написал:
Reply all
Reply to author
Forward
0 new messages