You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Gretchen A Chiaramonte <ch...@us.ibm.com> on 2008/06/13 19:34:31 UTC

Need OUTER JOIN to SecondaryTable


It seems to me that I can't be the only person that ever wanted an outer
join to a secondary table, but I have spent a whole day searching the
internet for a solution, and haven't seen one (except for a
Hibernate-specific one).  I have a main employee table that may or may not
have some extra data populated in a related secondary table.  If there is
data in the secondary table, then I would like my Employee entity to have
those fields filled in.  If there isn't data for a given employee in the
secondary table, then I would like my Employee entity to have nulls in
those fields.  Right now, if there's no row in the secondary table for a
given employee, I get nothing.  Is there any way to force openjpa to do an
OUTER JOIN to the secondary table? I am using the version of openjpa that
comes in the WebSphere 6.1 feature pack, so I believe I am constrained to
use openjpa 1.0.1, unless someone can give me a method to replace the IBM
supplied jars.

Here's example code:

@Entity
@Table("EMPLOYEE")
@SecondaryTable("EMPLOYEE_EXTRA",
            pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPLOYEE_KEY"))

public class Employee implements java.io.Serializable {

      private static final long serialVersionUID = -3789770304634576481L;

      @Column(table="EMPLOYEE_EXTRA",
            name="EMPLOYEE_EXTRA_DATA",nullable=true)
      private String employeeExtraData;

      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name="EMPLOYEE_KEY")
      private Long employeeKey;

...etc

}

Gretchen Chiaramonte

Sun Certified Java Programmer
IBM Certified MQSeries Engineer
IBM  Systems & Technology Group, Development

Tel: 1-919-517-1750
Tie: 255-1750
email: chiaramg@us.ibm.com

Re: Need OUTER JOIN to SecondaryTable

Posted by Kevin Sutter <kw...@gmail.com>.
Gretchen,

On Fri, Jun 13, 2008 at 12:34 PM, Gretchen A Chiaramonte <
chiaramg@us.ibm.com> wrote:

>
> I am using the version of openjpa that
> comes in the WebSphere 6.1 feature pack, so I believe I am constrained to
> use openjpa 1.0.1, unless someone can give me a method to replace the IBM
> supplied jars.
>
> WebSphere continues to update the version of OpenJPA that is supported in
the Feature Pack via the 1.0.x service stream.  So, if this forum posting
produces a valid problem, the solution (once integrated in the 1.0.x branch)
will be picked up with the next fixpack provided by WebSphere.

Also, due to the WebSphere extensions to the base OpenJPA code, it is
difficult to "replace" the IBM supplied jars with a version of OpenJPA
beyond the 1.0.x service branch.  The InfoCenter does document how you can
configure an alternate persistence provider (ie. an alternate version of
OpenJPA), but then you will not have access to the WebSphere extensions.

Are you indicating that trunk (ie. 1.2.x) does not exhibit this problem
(since you asked about replacing the version provided by the Feature Pack)?
Or, was this just a general question?

Thanks,
Kevin

Re: Need OUTER JOIN to SecondaryTable

Posted by yan <ya...@gmail.com>.
3. Other implementation for MappingDefaults (no need to update it each time a
new field use the OuterJoinStrategy) : 

public class MyMappingDefaults extends PersistenceMappingDefaults {
    Map<String,Object> fieldsStrategies;
    
    public Object getStrategy(ValueMapping vm, Class type, boolean adapt) { 
        if
(!getFieldsStrategies().containsKey(vm.getFieldMapping().getFullName(true)))
{
            Class declaringClass = vm.getFieldMapping().getDeclaringType();
            String filedName = vm.getFieldMapping().getName();
            
            Field field = null;
            Strategy strategy = null;
            try {
                field = declaringClass.getDeclaredField(filedName);
                strategy = field.getAnnotation(Strategy.class);  
                
            } catch (Exception e) {
                // nothing to do, strategy remains null
            } 
            
            if (null == strategy) {
                fieldsStrategies.put(vm.getFieldMapping().getFullName(true), 
                        super.getStrategy(vm, type, adapt));
            }
            else {
                try {
                    System.out.println("Set strategy for field '" +
vm.getFieldMapping().getFullName(true) 
                            + "' : " + strategy.value());
                   
fieldsStrategies.put(vm.getFieldMapping().getFullName(true), 
                            Class.forName(strategy.value()).newInstance());
                } catch (Exception e) {
                    e.printStackTrace();
                   
fieldsStrategies.put(vm.getFieldMapping().getFullName(true), 
                            super.getStrategy(vm, type, adapt));                    
                }            
            }
           
        }        

        return
getFieldsStrategies().get(vm.getFieldMapping().getFullName(true)); 
    }

    public Map<String, Object> getFieldsStrategies() {
        if (null == fieldsStrategies) {
            fieldsStrategies = new HashMap<String, Object>();
        }
        return fieldsStrategies;
    } 
    
    
}
-- 
View this message in context: http://n2.nabble.com/Need-OUTER-JOIN-to-SecondaryTable-tp210713p1344503.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Need OUTER JOIN to SecondaryTable

Posted by Pinaki Poddar <pp...@apache.org>.
Hi,
  You can add a custom strategy to 'employeeExtraData' field which will
force OUTER JOIN during select.
Something as follows:

1. Extend a strategy:
  
   public class OuterJoinStrategy extends StringFieldStrategy {
	public int select(Select sel, OpenJPAStateManager sm, JDBCStore store,
			JDBCFetchConfiguration fetch, int eagerMode) {
		field.setJoinOuter(true); // force outer join -- 'field' is a protected
field of super class
		return super.select(sel, sm, store, fetch, eagerMode);
	}
    }

2.  plug that strategy via annotation as:
      @Column(table="EMPLOYEE_EXTRA",
            name="EMPLOYEE_EXTRA_DATA",nullable=true)
      @Strategy(value="some.package.OuterJoinStrategy")
      private String employeeExtraData;

3. change MappingDefaults to use that strategy
    
    public class MyMappingDefaults extends PersistenceMappingDefaults {
	FieldStrategy outerJoinStrategy = new OuterJoinStrategy();
	public Object getStrategy(ValueMapping vm, Class type, boolean adapt) {
		if
("Employee.employeeExtraData".equals(vm.getFieldMapping().getFullName(true)))
{
			return outerJoinStrategy;
		}
		return super.getStrategy(vm, type, adapt);
	}
    }


4. finally Configure your mapping defaults in persistence.xml
    <property name="openjpa.jdbc.MappingDefaults"
value="some.package.MyMappingDefaults"/>


 It may be a mere flip of a switch to change the INNER JOIN to OUTER for
fields mapped to secondary tables, but I can not find it.



gretchch wrote:
> 
> 
> 
> It seems to me that I can't be the only person that ever wanted an outer
> join to a secondary table, but I have spent a whole day searching the
> internet for a solution, and haven't seen one (except for a
> Hibernate-specific one).  I have a main employee table that may or may not
> have some extra data populated in a related secondary table.  If there is
> data in the secondary table, then I would like my Employee entity to have
> those fields filled in.  If there isn't data for a given employee in the
> secondary table, then I would like my Employee entity to have nulls in
> those fields.  Right now, if there's no row in the secondary table for a
> given employee, I get nothing.  Is there any way to force openjpa to do an
> OUTER JOIN to the secondary table? I am using the version of openjpa that
> comes in the WebSphere 6.1 feature pack, so I believe I am constrained to
> use openjpa 1.0.1, unless someone can give me a method to replace the IBM
> supplied jars.
> 
> Here's example code:
> 
> @Entity
> @Table("EMPLOYEE")
> @SecondaryTable("EMPLOYEE_EXTRA",
>             pkJoinColumns=@PrimaryKeyJoinColumn(name="EMPLOYEE_KEY"))
> 
> public class Employee implements java.io.Serializable {
> 
>       private static final long serialVersionUID = -3789770304634576481L;
> 
>       @Column(table="EMPLOYEE_EXTRA",
>             name="EMPLOYEE_EXTRA_DATA",nullable=true)
>       private String employeeExtraData;
> 
>       @Id
>       @GeneratedValue(strategy=GenerationType.IDENTITY)
>       @Column(name="EMPLOYEE_KEY")
>       private Long employeeKey;
> 
> ...etc
> 
> }
> 
> Gretchen Chiaramonte
> 
> Sun Certified Java Programmer
> IBM Certified MQSeries Engineer
> IBM  Systems & Technology Group, Development
> 
> Tel: 1-919-517-1750
> Tie: 255-1750
> email: chiaramg@us.ibm.com
> 

-- 
View this message in context: http://www.nabble.com/Need-OUTER-JOIN-to-SecondaryTable-tp17828716p17869475.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.