[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2690?page=c...
]
Carl Gilbert commented on HHH-2690:
-----------------------------------
I am using postgres 8.1 with driver 8.1-409 and java 1.5.0_11
Same problem. Fell back to 3.2.0.ga and its working again.
My mapping is just about the same.
dbvariant.hbm.xml
[code]
<hibernate-mapping>
<joined-subclass name="com.rgdsft.hib.core.DBVariant"
table="VARIANT" extends="com.rgdsft.hib.core.DBNamedObject">
<key column="OBJECT_ID"/>
<properties name="uniqueVirtualSysNameConstraint"
unique="true">
<property name="name" not-null="true"
type="string"/>
<many-to-one name="project"
class="com.rgdsft.hib.core.DBProject" column="ProjectID"
not-null="true" lazy="proxy"/>
</properties>
<!-- problem here because we do not want the variant referenced by the
variantcollholder. That would interfere with the serialization. Since we
do not put the variant in the holder, we can not get hibernate to create the
foreign key constraints that I would want here. What I want is unique
(variant,system)
also maybe not-null in the systemID key?
-->
<map name="varholderMap" table="VARHOLDER_MAP"
access="field" cascade="all,delete-orphan">
<key column="DBVariant_ID" not-null="true"/>
<map-key-many-to-many column="KEY_SystemID"
class="com.rgdsft.hib.core.DBSystem"/>
<one-to-many class="com.rgdsft.hib.core.VariantCollHolder"/>
</map>
</joined-subclass>
</hibernate-mapping>
<hibernate-mapping>
<joined-subclass name="com.rgdsft.hib.core.DBNamedObject"
abstract="true" extends="com.rgdsft.hib.core.DBObject">
<key column="OBJECT_ID"/>
<map name="properties" table="PROPERTIES"
access="field">
<key column="DBNamedObject_ID" not-null="true"/>
<map-key-many-to-many column="PROPERTY_ID"
class="com.rgdsft.hib.core.DBPropertyType"/>
<element column="PROPERTY_VALUE" type="string"
not-null="true"/>
</map>
</joined-subclass>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.rgdsft.hib.core.DBObject" abstract="true">
<id name="id" column="OBJECT_ID">
<generator class="native"/>
</id>
<property name="identifier" not-null="true"
unique="true"/>
</class>
</hibernate-mapping>
[/code]
VariantCollHolder.hbm.xml
[code]
<hibernate-mapping>
<class name="com.rgdsft.hib.core.VariantCollHolder"
table="VARIANTCOLLHOLDER" lazy="false">
<id name="id" type="long">
<generator class="native"/>
</id>
<!-- no cascading here since we will only ever deal in remove/add from
collection and deal in querying values from the comp instance -->
<set name="instances" table="COMPINST_VARIANT"
lazy="false" access="field">
<key column="VariantID"/> <!-- change to varCollHolderID -->
<many-to-many column="CompinstanceID"
class="com.rgdsft.hib.core.DBComponentInstance"/>
</set>
<!-- no cascading here since we will only ever deal in remove/add from
collection and deal in querying values from the comp instance -->
<set name="connections" table="CONNECTION_VARIANT"
lazy="false" access="field">
<key column="VariantID"/> <!-- change to varCollHolderID -->
<many-to-many column="ConnectionID"
class="com.rgdsft.hib.core.DBFunctionConnection"/>
</set>
</class>
</hibernate-mapping>
[/code]
And a few classes
[code]
public class DBVariant extends DBNamedObject {
private String name;
private DBProject project;
private Map<DBSystem,VariantCollHolder> varholderMap = new
HashMap<DBSystem,VariantCollHolder>();//not in default fetch
public DBVariant(String name, DBProject project, Long identifier) {
super(identifier);
assert name != null;
assert project != null;
this.name = name;
this.project = project;
}
DBVariant(){
}
//edited-Not a test case
}
public final class VariantCollHolder implements Serializable {
private static final long serialVersionUID = 1L;
/*
* Hibernate spec version 3.2.0.ga section 4.1.2 states that transitive
* reattachment of detached objects requires an identifier. So we have one.
*/
private Long id; // identifier
/**
* The set of component instances in the associated variant.
*/
private Set<DBComponentInstance> instances = new
HashSet<DBComponentInstance>();
/**
* The set of connections in the associated variant.
*/
private Set<DBFunctionConnection> connections = new
HashSet<DBFunctionConnection>();
private transient boolean dirty;
public VariantCollHolder() {
}
/**
* @return the instances
*/
public Set<DBComponentInstance> getInstances() {
return instances;
}
/**
* @param instances the instances to set
*/
void setInstances(Set<DBComponentInstance> instances) {
this.instances = instances;
}
/**
* @return the connections
*/
public Set<DBFunctionConnection> getConnections() {
return connections;
}
/**
* @param connections the connections to set
*/
void setConnections(Set<DBFunctionConnection> connections) {
this.connections = connections;
}
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
}
public abstract class DBNamedObject extends DBObject {
private Map<DBPropertyType,String> properties = new
HashMap<DBPropertyType,String>();//not in default fetch
public DBNamedObject(Long identifier) {
super(identifier);
}
DBNamedObject(){
}
/************************ Begin Property Stuff ****************************/
public final Set<DBPropertyType> getPropertyKeys(){
return properties.keySet();
}
/*
* This probably works but is less efficient than calling for the key set
* and constructing objects that way. At least to the WAD object because
* we construct a map here, and they will have to construct a new map there.
*/
public Map<DBPropertyType,String> getProperties(){
return properties;
}
public String getProperty(DBPropertyType key) {
return properties.get(key);
}
public String setProperty(DBPropertyType key, String value){
return properties.put(key,value);
}
/************************ End Property Stuff ******************************/
public abstract String getName();
public abstract void setName(String name);
}
public abstract class DBObject {
/*
* Hibernate spec version 3.2.0.ga section 4.1.2 states that transitive
* reattachment of detached objects requires an identifier. So we have one.
*/
private Long id;
private Long identifier;
/*
* An object is dirty when it is modified.
*/
private transient boolean dirty;
DBObject(){
}
public DBObject(Long identifier) {
assert identifier != null;
this.identifier = identifier;
}
private void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public Long getIdentifier() {
return identifier;
}
private void setIdentifier(Long identifier) {
this.identifier = identifier;
}
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
//we need a system based on something that does not change and is assignable at commit
time
//I think identifier does not change and is assignable at commit time!
@Override
public boolean equals(Object obj) {
if(obj instanceof DBObject){
return ((DBObject)obj).identifier.equals(identifier);
}
return false;
}
@Override
public int hashCode() {
return identifier.hashCode();
}
/**
* Do not show hashcode if equals is not based on hashcode
*/
@Override
public String toString() {
return "(" + getClass().getSimpleName() + "::" + identifier
+"@" + super.hashCode() +")";
}
}
[/code]
Cascade delete and ternary association after upgrade
----------------------------------------------------
Key: HHH-2690
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2690
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.4.sp1
Environment: hsqldb, jvm 1.6.0_01-ea, ubuntu
Reporter: Przemek Dyk
Attachments: manytest.zip
My classes:
public class Product {
private long id;
private String name;
private Map/*<Attribute,AttributeValue>*/ attributeValues;
//getters/setters/hashcode/equals
}
public class AttributeValue {
private long id;
private String value;
private Product product;
private Attribute attribute;
//getters/setters/hashcode/equals
}
public class Attribute {
private long id;
private String name;
//getters/setters/hashcode/equals
}
Fragment of mapping:
<class name="Product">
<id name="id" column="id" type="long"
unsaved-value="0">
<generator class="native"/>
</id>
<property name="name" not-null="true"/>
<map name="attributeValues" lazy="true"
inverse="false" cascade="all-delete-orphan">
<key column="product_id" not-null="true"/>
<map-key-many-to-many column="attribute_id"
class="Attribute"/>
<one-to-many class="AttributeValue"/>
</map>
</class>
... and my exception after upgrading hibernate in my application.
2007-06-27 20:08:54 org.hibernate.property.BasicPropertyAccessor$BasicGetter get
SEVERE: IllegalArgumentException in class: com.mycompany.Attribute, getter method of
property: id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter
of com.mycompany.Attribute.id
at
org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
at
org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
at
org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3591)
at
org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3307)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:181)
at org.hibernate.engine.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:137)
at
org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:69)
at
org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:47)
at
org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:248)
at
org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:141)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:775)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:758)
at org.hibernate.engine.CascadingAction$2.cascade(CascadingAction.java:121)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at
org.hibernate.event.def.DefaultDeleteEventListener.cascadeBeforeDelete(DefaultDeleteEventListener.java:307)
at
org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:246)
at
org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:141)
at
org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:52)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:744)
I've tried many versions of hibernate using test from attachment
( mvn -Dhibernate.version=<version> clean compile test ) and I think that
bug was introduced between 3.2.0.ga and 3.2.1.ga
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira