-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Unidirectional @ManyToOne and Automatic Inner Joins
PostPosted: Fri Jul 24, 2009 9:59 am 
Newbie

Joined: Thu Jul 23, 2009 12:32 pm
Posts: 5
I have 2 entities. EntityOne has a @ManyToOne association with EntityTwo. EntityTwo has no association with EntityOne. This query

"select e from EntityOne e where e.code = 'ABC'"

results in two queries: one for EntityOne and another for EntityTwo. How can I force an inner join without having to specify it in the query?


Top
 Profile  
 
 Post subject: Re: Unidirectional @ManyToOne and Automatic Inner Joins
PostPosted: Mon Jul 27, 2009 3:09 pm 
Newbie

Joined: Thu Jul 23, 2009 12:32 pm
Posts: 5
To be more concrete here is my example, going against Apache Derby.
Code:
package hello;

import javax.persistence.*;

@Entity
public class InsurancePlan {
    @Id @GeneratedValue
    private Long id;
   
    private String name;
   
    @ManyToOne(fetch=FetchType.EAGER, optional = false)
    @JoinColumn(name = "plan_type_id")
    private InsurancePlanType planType;
   
    @SuppressWarnings("unused")
    private InsurancePlan() { }

    public InsurancePlan(String name, InsurancePlanType planType) {
        this.name = name;
        this.planType = planType;
    }

    public Long getId() {
        return id;
    }
   
    public String getName() {
        return name;
    }
   
    public InsurancePlanType getInsurancePlanType() {
        return planType;
    }   
}



and
Code:
package hello;

import javax.persistence.*;

@Entity
public class InsurancePlanType {
    @Id @GeneratedValue
    private Long id;
   
    private String name;
   
    @SuppressWarnings("unused")
    private InsurancePlanType() {}
   
    public InsurancePlanType(String name) {
        this.name = name;
    }
   
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

   
}



This test
Code:
package hello;


import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.BeforeClass;
import org.junit.Test;


public class InsurancePlanTest {
    private static EntityManagerFactory entityManagerFactory;
    private EntityManager em;
    private List<InsurancePlan> plans;
   
    @BeforeClass
    public static void createPersistence() {
        entityManagerFactory = Persistence.createEntityManagerFactory("helloworld");
    }
   
   
    @SuppressWarnings("unchecked")
    @Test
    public void createAndSearch() {
        em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        InsurancePlanType planTypeA = new InsurancePlanType("A plan type");
        InsurancePlanType planTypeB = new InsurancePlanType("B plan type");
        em.persist(planTypeA);
        em.persist(planTypeB);
        em.persist(new InsurancePlan("1 plan", planTypeA));
        em.persist(new InsurancePlan("2 plan", planTypeA));
        em.persist(new InsurancePlan("3 plan", planTypeB));
        em.flush();
        em.getTransaction().commit();
        em.close();
       
        em = entityManagerFactory.createEntityManager();
        em.getTransaction().begin();
        plans = em.createQuery("select p from InsurancePlan p").getResultList();
        for (InsurancePlan plan : plans) {
            System.out.println(plan.getName());
            System.out.println(plan.getInsurancePlanType().getName());
        }
        em.getTransaction().commit();
    }
   
}


results in these queries: (notice the multiple selects against the "one" table).

Code:
Hibernate:
    insert
    into
        insurance_plan_type
        (name, id)
    values
        (?, ?)
Hibernate:
    insert
    into
        insurance_plan_type
        (name, id)
    values
        (?, ?)
Hibernate:
    insert
    into
        insurance_plan
        (name, plan_type_id, id)
    values
        (?, ?, ?)
Hibernate:
    insert
    into
        insurance_plan
        (name, plan_type_id, id)
    values
        (?, ?, ?)
Hibernate:
    insert
    into
        insurance_plan
        (name, plan_type_id, id)
    values
        (?, ?, ?)
Hibernate:
    select
        insurancep0_.id as id0_,
        insurancep0_.name as name0_,
        insurancep0_.plan_type_id as plan3_0_
    from
        insurance_plan insurancep0_
Hibernate:
    select
        insurancep0_.id as id2_0_,
        insurancep0_.name as name2_0_
    from
        insurance_plan_type insurancep0_
    where
        insurancep0_.id=?
Hibernate:
    select
        insurancep0_.id as id2_0_,
        insurancep0_.name as name2_0_
    from
        insurance_plan_type insurancep0_
    where
        insurancep0_.id=?


Is this done to make sure that there is only instance of each item in the one side of the relationship? It seems it would be more efficient to just go ahead an do a join and toss out the duplicates from the one side.


Top
 Profile  
 
 Post subject: Re: Unidirectional @ManyToOne and Automatic Inner Joins
PostPosted: Mon Jul 27, 2009 3:38 pm 
Newbie

Joined: Thu Jul 23, 2009 12:32 pm
Posts: 5
Adding JOIN FETCH to the query works. I did expect, however, that something like this would preclude the need for the query change:

@ManyToOne(optional = false)
@JoinColumn(name = "plan_type_id")
@Fetch(FetchMode.JOIN)
private InsurancePlanType planType;

This didn't work, though.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.