Really there is no query involved (I mean I wrote). 
Also here is another entity might be mentioned "

@Entity
@Table(name="USER_PROFILE")
public class UserProfile {
        @Transient public static final int ROLE_ADMIN           = 0;
        @Transient public static final int ROLE_COMPANY         = 1;
        @Transient public static final int ROLE_STORE           = 2;
        
        @Id
        @Column(name="USER_ID",                 columnDefinition="VARCHAR(10)", 
nullable=false)
        private String name = null;

        @Column(name="USER_ROLE",               columnDefinition="INTEGER", 
nullable=false)
        private int role = ROLE_STORE; 
        
        @ManyToMany(fetch=FetchType.EAGER)
        @JoinTable(name="USER_PROFILE_COMPANY",
                [EMAIL PROTECTED](name="USER_ID", 
referencedColumnName="USER_ID"),
                [EMAIL PROTECTED](name="SCHEMA_ID",
referencedColumnName="SCHEMA_ID")
        )
        private List<UserCompany> companies = new ArrayList<UserCompany>();
        
        @ManyToMany(fetch=FetchType.EAGER)
        @JoinTable(name="USER_PROFILE_STORE",
                [EMAIL PROTECTED](name="USER_ID", 
referencedColumnName="USER_ID"),
                [EMAIL PROTECTED](name="SCHEMA_ID",
referencedColumnName="SCHEMA_ID")
        )

And in program I was just calling userProfile.getCompanies().
Because fetch is EAGER it was getting it by itself. What I really expected
and needed. )
I didn't expected though it will get rach store entity in different select.

Though I have made OpenJPA select it my way (one select per company).
In order to do that I had to change EAGER to LAZY on UserCompany like this :

@Entity
@DiscriminatorValue(value="COMPANY")
public class UserCompany extends UserSchema {

        @OneToMany(mappedBy="company")
        private List<UserStore> stores = new ArrayList<UserStore>();

and in calling program do it manually. Also it might happen that UserProfile
involved in this mess too
since it has relation to stores too. When I changed EAGER to LAZY and added
manual call in client it started working right. (Added call marked bold and
italic)
Here is how I am calling it from client program :

                EntityManager em = emf.createEntityManager();
                currentUser = em.find(UserProfile.class, userName);
                if (currentUser != null) {
                        List<UserCompany> list = currentUser.getCompanies();
                        currentUser.getStores();
                        for (UserCompany userCompany : list) {
                                userCompany.getStores();
                        }
                }
                em.close();



Marc Prud'hommeaux wrote:
> 
> Andrey-
> 
> 
>> Didn't we already selected all what we need with first select ????
>>
>> SELECT t0.SCHEMA_ID, t0.DTYPE, t0.NAME FROM USER_SCHEMA t0 WHERE
>> t0.company_SCHEMA_ID = ? [params=(String) AAZ01.0000]
>>
>> Why all the per store sql requests executed?
> 
> Are you running the query against the "UserSchema" entity, or against  
> the "UserCompany"? If it is the "UserSchema", then in the initial  
> select, OpenJPA doesn't make any assumptions about which subclass  
> might actually will be returned. So when each item UserCompany  
> instance iterated over in the results, its eager "company" OneToMany  
> field is loaded, causing the join to happen for each instance.
> 
> I think that if your query is against "UserCompany" (e.g., "select x  
> from UserCompany x"), then you might not see the join happen for each  
> returned instance.
> 
> 
> 
> On Jul 23, 2007, at 12:20 PM, Andrey Tedeev wrote:
> 
>>
>> I have 3 entities described below (gettters and setters are cut for
>> readability):
>> ---------------------------------------------------------------------- 
>> -----------------
>> @Entity
>> @Table(name="USER_SCHEMA")
>> @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
>> @DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,
>> name="DTYPE")
>>
>> public abstract class UserSchema {
>>
>>      @Id
>>      @Column(name="SCHEMA_ID",               columnDefinition="VARCHAR(100)",
>> nullable=false)
>>      private String schema = null;
>>      
>>      @Column(name="NAME",                    
>> columnDefinition="VARCHAR(100)",  
>> nullable=false)
>>      private String name = null;
>> ...
>> ---------------------------------------------------------------------- 
>> -----------------
>> @Entity
>> @DiscriminatorValue(value="COMPANY")
>> public class UserCompany extends UserSchema {
>>
>>      @OneToMany(mappedBy="company", fetch=FetchType.EAGER)
>>      private List<UserStore> stores = new ArrayList<UserStore>();
>>
>> ...
>>
>> @Entity
>> @DiscriminatorValue(value="STORE")
>> public class UserStore extends UserSchema {
>>
>>      @ManyToOne
>>      private UserCompany company = null;
>>
>> ...
>> ---------------------------------------------------------------------- 
>> -----------------
>> SQL Table generated properly by Mapped Tool and has expected  
>> structure :
>>
>> CREATE TABLE USER_SCHEMA (
>>      SCHEMA_ID VARCHAR(100) NOT NULL ,
>>      NAME VARCHAR(100) NOT NULL ,
>>      DTYPE VARCHAR(31) DEFAULT NULL ,
>>      COMPANY_SCHEMA_ID  VARCHAR(100) DEFAULT NULL ,
>>      CONSTRAINT PRIMARY KEY( SCHEMA_ID ) ) ;
>> ---------------------------------------------------------------------- 
>> -----------------
>> I inserted some data into tables. Company with id = AAZ01.0000 and  
>> Stores
>> with ids (AAZ01.0070, AAZ01.0135 etc. which belong to AAZ01.0000
>> (COMPANY_SCHEMA_ID = AAZ01.0000).
>> Now I'm reading data from database and when UserCompany reads it's
>> UserStores
>> I can see in SQL TRACE that OpenJPA creates one sql select request  
>> per each
>> store of the company like this :
>>
>> 3329  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> executing prepstmnt 30362156 SELECT t0.SCHEMA_ID, t0.DTYPE, t0.NAME  
>> FROM
>> USER_SCHEMA t0 WHERE t0.company_SCHEMA_ID = ? [params=(String)  
>> AAZ01.0000]
>> 3585  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> [256 ms] spent
>> 3838  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> executing prepstmnt 28171097 SELECT t1.SCHEMA_ID, t1.DTYPE, t1.NAME  
>> FROM
>> USER_SCHEMA t0 INNER JOIN USER_SCHEMA t1 ON t0.company_SCHEMA_ID =
>> t1.SCHEMA_ID WHERE t0.SCHEMA_ID = ? [params=(String) AAZ01.0070]
>> 4088  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> [250 ms] spent
>> 4566  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> executing prepstmnt 13359904 SELECT t1.SCHEMA_ID, t1.DTYPE, t1.NAME  
>> FROM
>> USER_SCHEMA t0 INNER JOIN USER_SCHEMA t1 ON t0.company_SCHEMA_ID =
>> t1.SCHEMA_ID WHERE t0.SCHEMA_ID = ? [params=(String) AAZ01.0135]
>> 4823  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> [257 ms] spent
>> 5328  ssi.jpa  TRACE  [main] openjpa.jdbc.SQL - <t 10038190, conn  
>> 179514>
>> executing prepstmnt 15177785 SELECT t1.SCHEMA_ID, t1.DTYPE, t1.NAME  
>> FROM
>> USER_SCHEMA t0 INNER JOIN USER_SCHEMA t1 ON t0.company_SCHEMA_ID =
>> t1.SCHEMA_ID WHERE t0.SCHEMA_ID = ? [params=(String) AAZ01.0140]
>>
>>
>> !!! FINALLY THE QUESTION :
>>
>> Didn't we already selected all what we need with first select ????
>>
>> SELECT t0.SCHEMA_ID, t0.DTYPE, t0.NAME FROM USER_SCHEMA t0 WHERE
>> t0.company_SCHEMA_ID = ? [params=(String) AAZ01.0000]
>>
>> Why all the per store sql requests executed?
>>
>>
>> -- 
>> View this message in context: http://www.nabble.com/ 
>> InheritanceType.SINGLE_TABLE-generated-sql-selects- 
>> tf4131850.html#a11750927
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/InheritanceType.SINGLE_TABLE-generated-sql-selects-tf4131850.html#a11754781
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to