You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-user@db.apache.org by cbeams <cb...@gmail.com> on 2007/09/01 09:14:08 UTC

Query by interface

As a user, here's what I would expect to work:


	@PersistenceCapable(table="person")
	public interface Person {}

	@PersistenceCapable(table="person")
	public class MyPerson implements Person {}


	public class Main {
		public static void main(String... args) {
			PersistenceManagerFactory pmf =  
JDOHelper.getPersistenceManagerFactory("pmf.properties");
			PersistenceManager pm = pmf.getPersistenceManager();
			
			pm.currentTransaction().begin();
			pm.makePersistent(new MyPerson());  // persist the concrete type
			pm.currentTransaction().commit();

			Query query = pm.newQuery(Person.class);  // query by the interface
			query.setUnique(true);
			Person person = (Person)query.execute();

			assert person instanceof MyPerson == true;
		}	
	}

This does not work, however (at least with JPOX).  My instanceof  
assertion at bottom fails, because person is actually a type  
generated by the implementation (PersonImpl in the case of JPOX).   
While I understand that this class generation approach may have some  
uses, I'm actually dealing with I believe is a much simpler use case  
that doesn't seem to be supported:  I simply want to be able to  
persist an instance of a concrete type and subsequently query for  
that object by it's interface.

Am I missing something?  Note that I'm not looking for any JPOX- 
specific tips here; just some guidance on usage per the spec.

Thanks,

- Chris

Chris Beams








Re: Query by interface

Posted by Craig L Russell <Cr...@Sun.COM>.
Hi Chris,

I guess you mapped both Person and MyPerson to the same tables in the  
database (and didn't add a discriminator column to distinguish Person  
from MyPerson). So the implementation thinks you want a generated  
Person to be constructed from the database rows.

The discussion of persistent interfaces has not been translated into  
spec-language, and this is one of several use cases that need to be  
discussed.

But for now, what if you don't map Person to the database?

Craig

On Sep 1, 2007, at 12:14 AM, cbeams wrote:

>
> As a user, here's what I would expect to work:
>
>
> 	@PersistenceCapable(table="person")
> 	public interface Person {}
>
> 	@PersistenceCapable(table="person")
> 	public class MyPerson implements Person {}
>
>
> 	public class Main {
> 		public static void main(String... args) {
> 			PersistenceManagerFactory pmf =  
> JDOHelper.getPersistenceManagerFactory("pmf.properties");
> 			PersistenceManager pm = pmf.getPersistenceManager();
> 			
> 			pm.currentTransaction().begin();
> 			pm.makePersistent(new MyPerson());  // persist the concrete type
> 			pm.currentTransaction().commit();
>
> 			Query query = pm.newQuery(Person.class);  // query by the interface
> 			query.setUnique(true);
> 			Person person = (Person)query.execute();
>
> 			assert person instanceof MyPerson == true;
> 		}	
> 	}
>
> This does not work, however (at least with JPOX).  My instanceof  
> assertion at bottom fails, because person is actually a type  
> generated by the implementation (PersonImpl in the case of JPOX).   
> While I understand that this class generation approach may have  
> some uses, I'm actually dealing with I believe is a much simpler  
> use case that doesn't seem to be supported:  I simply want to be  
> able to persist an instance of a concrete type and subsequently  
> query for that object by it's interface.
>
> Am I missing something?  Note that I'm not looking for any JPOX- 
> specific tips here; just some guidance on usage per the spec.
>
> Thanks,
>
> - Chris
>
> Chris Beams
>
>
>
>
>
>
>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: Query by interface

Posted by cbeams <cb...@gmail.com>.
Here's another, perhaps even simpler cut at it:

@PersistenceCapable
public interface Person {}

@PersistenceCapable
@Implements(Person.class)
public class MyPerson implements Person {}

public class Main {

     @SuppressWarnings("unchecked")
     public static void main(String... args) {
         PersistenceManagerFactory pmf =  
JDOHelper.getPersistenceManagerFactory("jpox.properties");
         PersistenceManager pm = pmf.getPersistenceManager();
         Person inst = new MyPerson();

         System.out.println(inst);

         pm.currentTransaction().begin();
         pm.makePersistent(inst);
         pm.currentTransaction().commit();

         System.out.println(pm.newQuery(pm.getExtent(Person.class,  
true)).execute());
     }

}


When running the above, JPOX auto-creates the following schema:

CREATE
     TABLE myperson
     (
         myperson_id bigint(20) NOT NULL,
         PRIMARY KEY USING BTREE (myperson_id)
     )

CREATE
     TABLE personimpl
     (
         personimpl_id bigint(20) NOT NULL,
         PRIMARY KEY USING BTREE (personimpl_id)
     )


The output of the main() method is as follows:

org.jpox.test.MyPerson@7c28c
[]


After running, the MYPERSON table has 1 row (as expected), the  
PERSONIMPL table has 0 rows.

The query in the main method is only pulling back rows from the  
PERSONIMPL table, thus the empty list.

It seems strange to me that the implementation is creating its own  
implementation (PersonImpl) when I've clearly expressed that I want  
to provide my own (MyPerson).

Thanks,

- Chris

P.S.: the results are the same whether I use an extent as above, or  
just directly query on the interface.


On Sep 1, 2007, at 8:53 AM, Erik Bengtson wrote:

> Chris,
>
> I think you have to use the Implements annotation. Something like:
>
> 	@PersistenceCapable(table="person")
> @Implements(Person.class)
> 	public class MyPerson implements Person {}
>
>
>
> -----Message d'origine-----
> De : cbeams [mailto:cbeams@gmail.com]
> Envoyé : samedi 1 septembre 2007 9:14
> À : jdo-user@db.apache.org
> Objet : Query by interface
>
>
> As a user, here's what I would expect to work:
>
>
> 	@PersistenceCapable(table="person")
> 	public interface Person {}
>
> 	@PersistenceCapable(table="person")
> 	public class MyPerson implements Person {}
>
>
> 	public class Main {
> 		public static void main(String... args) {
> 			PersistenceManagerFactory pmf =
> JDOHelper.getPersistenceManagerFactory("pmf.properties");
> 			PersistenceManager pm = pmf.getPersistenceManager();
> 			
> 			pm.currentTransaction().begin();
> 			pm.makePersistent(new MyPerson());  // persist the
> concrete type
> 			pm.currentTransaction().commit();
>
> 			Query query = pm.newQuery(Person.class);  // query
> by the interface
> 			query.setUnique(true);
> 			Person person = (Person)query.execute();
>
> 			assert person instanceof MyPerson == true;
> 		}	
> 	}
>
> This does not work, however (at least with JPOX).  My instanceof
> assertion at bottom fails, because person is actually a type
> generated by the implementation (PersonImpl in the case of JPOX).
> While I understand that this class generation approach may have some
> uses, I'm actually dealing with I believe is a much simpler use case
> that doesn't seem to be supported:  I simply want to be able to
> persist an instance of a concrete type and subsequently query for
> that object by it's interface.
>
> Am I missing something?  Note that I'm not looking for any JPOX-
> specific tips here; just some guidance on usage per the spec.
>
> Thanks,
>
> - Chris
>
> Chris Beams
>
>
>
>
>
>
>
>
>


RE: Query by interface

Posted by Erik Bengtson <er...@jpox.org>.
Chris,

I think you have to use the Implements annotation. Something like:

	@PersistenceCapable(table="person")
@Implements(Person.class)
	public class MyPerson implements Person {}



-----Message d'origine-----
De : cbeams [mailto:cbeams@gmail.com] 
Envoyé : samedi 1 septembre 2007 9:14
À : jdo-user@db.apache.org
Objet : Query by interface


As a user, here's what I would expect to work:


	@PersistenceCapable(table="person")
	public interface Person {}

	@PersistenceCapable(table="person")
	public class MyPerson implements Person {}


	public class Main {
		public static void main(String... args) {
			PersistenceManagerFactory pmf =  
JDOHelper.getPersistenceManagerFactory("pmf.properties");
			PersistenceManager pm = pmf.getPersistenceManager();
			
			pm.currentTransaction().begin();
			pm.makePersistent(new MyPerson());  // persist the
concrete type
			pm.currentTransaction().commit();

			Query query = pm.newQuery(Person.class);  // query
by the interface
			query.setUnique(true);
			Person person = (Person)query.execute();

			assert person instanceof MyPerson == true;
		}	
	}

This does not work, however (at least with JPOX).  My instanceof  
assertion at bottom fails, because person is actually a type  
generated by the implementation (PersonImpl in the case of JPOX).   
While I understand that this class generation approach may have some  
uses, I'm actually dealing with I believe is a much simpler use case  
that doesn't seem to be supported:  I simply want to be able to  
persist an instance of a concrete type and subsequently query for  
that object by it's interface.

Am I missing something?  Note that I'm not looking for any JPOX- 
specific tips here; just some guidance on usage per the spec.

Thanks,

- Chris

Chris Beams










Re: Query by interface

Posted by Craig L Russell <Cr...@Sun.COM>.
Hi Chris,

I guess you mapped both Person and MyPerson to the same tables in the  
database (and didn't add a discriminator column to distinguish Person  
from MyPerson). So the implementation thinks you want a generated  
Person to be constructed from the database rows.

The discussion of persistent interfaces has not been translated into  
spec-language, and this is one of several use cases that need to be  
discussed.

But for now, what if you don't map Person to the database?

Craig

On Sep 1, 2007, at 12:14 AM, cbeams wrote:

>
> As a user, here's what I would expect to work:
>
>
> 	@PersistenceCapable(table="person")
> 	public interface Person {}
>
> 	@PersistenceCapable(table="person")
> 	public class MyPerson implements Person {}
>
>
> 	public class Main {
> 		public static void main(String... args) {
> 			PersistenceManagerFactory pmf =  
> JDOHelper.getPersistenceManagerFactory("pmf.properties");
> 			PersistenceManager pm = pmf.getPersistenceManager();
> 			
> 			pm.currentTransaction().begin();
> 			pm.makePersistent(new MyPerson());  // persist the concrete type
> 			pm.currentTransaction().commit();
>
> 			Query query = pm.newQuery(Person.class);  // query by the interface
> 			query.setUnique(true);
> 			Person person = (Person)query.execute();
>
> 			assert person instanceof MyPerson == true;
> 		}	
> 	}
>
> This does not work, however (at least with JPOX).  My instanceof  
> assertion at bottom fails, because person is actually a type  
> generated by the implementation (PersonImpl in the case of JPOX).   
> While I understand that this class generation approach may have  
> some uses, I'm actually dealing with I believe is a much simpler  
> use case that doesn't seem to be supported:  I simply want to be  
> able to persist an instance of a concrete type and subsequently  
> query for that object by it's interface.
>
> Am I missing something?  Note that I'm not looking for any JPOX- 
> specific tips here; just some guidance on usage per the spec.
>
> Thanks,
>
> - Chris
>
> Chris Beams
>
>
>
>
>
>
>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!