openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Prud'hommeaux <mprud...@apache.org>
Subject Re: Funky Query from entityManager.find(Class,id)
Date Tue, 24 Apr 2007 18:19:58 GMT
Phill-

> It should not be selecting from two tables as it cannot create the  
> object. As I
> mentioned before (in the other thread) this causes the looked for  
> object to be
> null as if the object was not found. Here is my call statement

ManyToOne and OneToOne relations default to being eagerly fetched.  
You can override this by specifying fetch=LAZY in the @ManyToOne  
annotation.

That being said, I don't understand that problem. Are you saying that  
the lookup fails because there is no related attributetype row? That  
shouldn't prevent the lookup from happening, since we are using an  
outer join.



On Apr 23, 2007, at 11:20 PM, Phill Moran wrote:

> I posted this question before but I am now seeing it in several  
> places and can
> produce a test case for it. Here are two related classes (one-to- 
> many) attribute
> and attributeType, each with table/class inheritance.
>
>
> Attribute class:
> package ca.BidSpec.emall.categories;
>
> import javax.persistence.Basic;
> import javax.persistence.CascadeType;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.Inheritance;
> import javax.persistence.InheritanceType;
> import javax.persistence.JoinColumn;
> import javax.persistence.ManyToOne;
> import javax.persistence.NamedQueries;
> import javax.persistence.NamedQuery;
> import javax.persistence.Table;
>
> import ca.BidSpec.emall.commonServices.PrimaryKey;
> import ca.BidSpec.emall.persistence.Persistable;
>
> @Entity
> @Table(name = "attributes")
> @NamedQueries( {
> 		@NamedQuery(name = "AttributeFXPK", query = "SELECT a FROM
> Attribute a WHERE a.id = :primaryKey"),
> 		@NamedQuery(name = "AttributeFXDescription", query = "SELECT a
> FROM Attribute a WHERE a.value = :description ORDER BY a.value") })
> @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
> public class Attribute extends Persistable {
>
> 	private AttributeType type;
>
> 	private String value = "";
>
> 	/*
> 	 * required for persistence
> 	 */
> 	private Attribute() {
> 	}
>
> 	public Attribute(PrimaryKey pk) {
> 		this.setPrimaryKey(pk);
> 	}
>
> 	/**
> 	 * @param pk
> 	 *            this objects primary key
> 	 * @param type
> 	 *            this object attribute type
> 	 * @param value
> 	 *            the value for this attribute given it's type
> 	 */
> 	public Attribute(PrimaryKey pk, AttributeType type, String value) {
> 		this.setPrimaryKey(pk);
> 		this.setType(type);
> 		this.setValue(value);
> 	}
>
> 	@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH,
> CascadeType.MERGE })
> 	@JoinColumn(name = "attributeTypeFK")
> 	public AttributeType getType() {
> 		return type;
> 	}
>
> 	public void setType(AttributeType type) {
> 		this.type = type;
> 	}
>
> 	@Basic()
> 	@Column(name = "value", nullable = false, length = 50)
> 	public String getValue() {
> 		return value;
> 	}
>
> 	public void setValue(String value) {
> 		this.value = value;
> 	}
> }
>
>
> AttributeType Class
> package ca.BidSpec.emall.categories;
>
> import javax.persistence.Basic;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.Inheritance;
> import javax.persistence.InheritanceType;
> import javax.persistence.NamedQueries;
> import javax.persistence.NamedQuery;
> import javax.persistence.Table;
>
> import ca.BidSpec.emall.commonServices.PrimaryKey;
> import ca.BidSpec.emall.persistence.Persistable;
>
> @Entity
> @Table(name = "attributetype")
> @NamedQueries( {
> 		@NamedQuery(name = "AttributeTypeFXPK", query = "SELECT a FROM
> AttributeType a WHERE a.id = :primaryKey"),
> 		@NamedQuery(name = "AttributeTypeFXDescription", query = "SELECT
> a FROM AttributeType a WHERE a.description = :description ORDER BY
> a.description") })
> @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
> public class AttributeType extends Persistable {
> 	private String description = "";
>
> 	/*
> 	 * required for persistence
> 	 */
> 	private AttributeType() {
> 	}
>
> 	public AttributeType(PrimaryKey pk) {
> 		this.setPrimaryKey(pk);
> 	}
>
> 	public AttributeType(PrimaryKey pk, String description) {
> 		this.setPrimaryKey(pk);
> 		this.setDescription(description);
> 	}
>
> 	@Basic()
> 	@Column(name = "description", length = 50)
> 	public String getDescription() {
> 		return description;
> 	}
>
> 	/*
> 	 * Set this attribute type's description
> 	 */
> 	public void setDescription(String description) {
> 		this.description = description;
> 	}
> }
>
> Persistable is my based persistable class of all Entities:
>
> package ca.BidSpec.emall.persistence;
>
> import java.io.Serializable;
> import java.sql.Timestamp;
> import java.util.Date;
>
> import javax.persistence.Basic;
> import javax.persistence.Column;
> import javax.persistence.Id;
> import javax.persistence.MappedSuperclass;
> import javax.persistence.Temporal;
> import javax.persistence.TemporalType;
> import javax.persistence.Transient;
>
> import ca.BidSpec.emall.commonServices.PrimaryKey;
>
> @MappedSuperclass
> public abstract class Persistable implements Serializable {
>
> 	/**
> 	 * Comment for <code>id</code> This is a persistable objects  
> Primary id
> 	 */
>
> 	private String id;
>
> 	/**
> 	 * User record last updated
> 	 */
>
> 	private Timestamp lastUpdated = new Timestamp((new Date()).getTime 
> ());
>
> 	/**
> 	 * @return Returns the persistable objects id.
> 	 */
> 	@Id
> 	@Column(name = "id")
> 	protected String getId() {
> 		return this.id;
> 	}
>
> 	protected void setId(String theId) {
> 		this.id = theId;
> 	}
>
> 	/**
> 	 * @return this object id in a primary id object
> 	 */
> 	@Transient
> 	public PrimaryKey getPrimaryKey() {
> 		return new PrimaryKey(this.getId());
> 	}
>
> 	/**
> 	 * @param id
> 	 *            The id to set.
> 	 */
> 	public void setPrimaryKey(PrimaryKey primaryKey) {
> 		this.setId(primaryKey.getKey());
> 	}
>
> 	/**
> 	 * @return Returns the lastUpdated date for this object.
> 	 */
> 	@Basic
> 	@Temporal(TemporalType.TIMESTAMP)
> 	@Column(name = "lastUpdated")
> 	public Timestamp getLastUpdated() {
> 		return this.lastUpdated;
> 	}
>
> 	public void setLastUpdated(Timestamp lastUpdated) {
> 		this.lastUpdated = lastUpdated;
> 	}
>
> 	public boolean equals(Object obj) {
> 		if ((obj != null) && (obj instanceof Persistable)) {
> 			if (((Persistable) obj).getId().equals(this.getId())) {
> 				return true;
> 			}
> 		}
> 		return false;
> 	}
>
> 	public int hashCode() {
> 		return this.getId().hashCode();
> 	}
>
> Here is the query generated:
>
> 16360  TRACE  [main] openjpa.jdbc.SQL - <t 28346522, conn 30686131>  
> executing
> prepstmnt 17313093 SELECT t0.id, t0.lastUpdated, t1.id,  
> t1.lastUpdated,
> t1.description, t0.value FROM attributes t0 LEFT OUTER JOIN  
> attributetype t1 ON
> t0.attributeTypeFK = t1.id WHERE t0.id = ? [params=(String)
> 111e3a22-728a-86ce-0126-11a7acec229a:0]
>
> It should not be selecting from two tables as it cannot create the  
> object. As I
> mentioned before (in the other thread) this causes the looked for  
> object to be
> null as if the object was not found. Here is my call statement
>
> 		Attribute deleteObj = (Attribute)
> categoryFactory.getObjectByPK(Attribute.class,
> 				"111e3a22-728a-86ce-0126-11a7acec229a:0"); <-
> this ID exists in the table
> 		assertNotNull(deleteObj); <-- fails here
>
> getObjectBYPK is
>
> 	public Persistable getObjectByPK(Class<? extends Persistable>
> objectTypeBeingSought, String pk) {
> 		Persistable per = null;
> 		per = (Persistable)
> getEntityManager().find(objectTypeBeingSought, pk);
> 		return per;
> 	}
>
> }
>
> I think this may be a bug as I see it in several classes - but  
> frustratingly not
> all. Any suggestions
>
> Phill
>


Mime
View raw message