openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Phill Moran" <pjmo...@rogers.com>
Subject Funky Query from entityManager.find(Class,id)
Date Tue, 24 Apr 2007 06:20:54 GMT
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