-->
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.  [ 4 posts ] 
Author Message
 Post subject: One association value getting saved but other isn't
PostPosted: Tue Jan 27, 2009 3:54 am 
Newbie

Joined: Tue Jan 27, 2009 3:32 am
Posts: 4
Hibernate version:
3.3.1 GA

Name and version of the database you are using:
MySQL 5

The generated SQL (show_sql=true):
Hibernate: insert into product_type (name) values (?)
Hibernate: insert into attribute_definition (name, product_type_id) values (?, ?)
Hibernate: insert into attribute_definition (name, product_type_id) values (?, ?)
Hibernate: insert into attribute_definition (name, product_type_id) values (?, ?)
Hibernate: insert into attribute_definition (name, product_type_id) values (?, ?)
Hibernate: insert into attribute_definition (name, product_type_id) values (?, ?)
Hibernate: insert into product (brand, cond, long_description, model_no, price, product_type_id, short_description, sku, title, upc) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into attribute (name, product_id, value) values (?, ?, ?)
Hibernate: insert into attribute (name, product_id, value) values (?, ?, ?)
Hibernate: insert into attribute (name, product_id, value) values (?, ?, ?)
Hibernate: insert into attribute (name, product_id, value) values (?, ?, ?)
Hibernate: insert into attribute (name, product_id, value) values (?, ?, ?)

I am developing a model that supports arbitrary attributes. Concretely, a Product can have one or more attributes in addition to standard fare (title, description, modelNo, sku, etc). The extra attributes are based off a ProductType, so for instance a Product could have a ProductType of "Laptop Computer"

Code:
ProductType type = new ProductType();
type.setName("Laptop Computer");
type.addAttributeDefinition(new AttributeDefinition("Screen Size"));
type.addAttributeDefinition(new AttributeDefinition("Screen Resolution"));
type.addAttributeDefinition(new AttributeDefinition("Processor Speed"));
type.addAttributeDefinition(new AttributeDefinition("RAM"));
type.addAttributeDefinition(new AttributeDefinition("Battery Life"));
productService.saveProductType(type);


Here is how I create the product:

Code:
Product product = new Product();
product.setTitle("Dell Precision M6300");
product.setBrand("Dell");
product.setCondition("New");
product.setModelNo("M6300");
product.setShortDescription("A perfect laptop for demanding users");
product.setProductType(type);


setProductType above isn't a standard setter. It does a little bit more:

Code:
public void setProductType(ProductType productType) {
   this.productType = productType;
   
   for (AttributeDefinition definition : productType.getAttributeDefinitions()) {
      Attribute attribute = new Attribute();
      attribute.setName(definition.getName());
      attribute.setValue("")
      attributes.put(attribute.getName(), attribute);
      attribute.setProduct(this);         
   }
}


So a ProductType is responsible for defining attribute definitions through the AttributeDefinition class. When I want to set the value of actual attributes, I call this convenience method on Product:

Code:
public void setAttribute(String name, String value) {
   if (!attributes.containsKey(name)) {
      throw new IllegalArgumentException("no attribute with name " + name);
   }
   
   Attribute attribute = attributes.get(name);
   attribute.setValue(value);
}


So I can do this:

Code:
product.setAttribute("Screen Size", "17in");
product.setAttribute("Screen Resolution", "1280x1024");
product.setAttribute("Processor Speed", "2.80 Ghz");
product.setAttribute("RAM", "8 Gb");
product.setAttribute("Battery Life", "30 minutes");


After setting these attributes, I do a productService.saveProduct(product). The product gets written to the DB as do the attributes, but curiously, the name property of Attribute is saved while the value property is not. The strange thing is that if I call saveProduct() both before and after the code above, both values are saved correctly. I don't understand what's going on.

Here is the full listing of what I am doing:

Code:
ProductType type = new ProductType();
type.setName("Laptop Computer");
type.addAttributeDefinition(new AttributeDefinition("Screen Size"));
type.addAttributeDefinition(new AttributeDefinition("Screen Resolution"));
type.addAttributeDefinition(new AttributeDefinition("Processor Speed"));
type.addAttributeDefinition(new AttributeDefinition("RAM"));
type.addAttributeDefinition(new AttributeDefinition("Battery Life"));

productService.saveProductType(type);

// create a product
Product product = new Product();
product.setTitle("Dell Precision M6300");
product.setBrand("Dell");
product.setCondition("New");
product.setModelNo("M6300");
product.setShortDescription("A perfect laptop for demanding users");
product.setProductType(type);

// additional attributes
product.setAttribute("Screen Size", "17in");
product.setAttribute("Screen Resolution", "1280x1024");
product.setAttribute("Processor Speed", "2.80 Ghz");
product.setAttribute("RAM", "8 Gb");
product.setAttribute("Battery Life", "30 minutes");

productService.saveProduct(product); // the attribute keys are saved but not the values


Here is what the DB looks like:

Code:
mysql> select * from attribute;
+----+-------------------+-------+------------+
| id | name              | value | product_id |
+----+-------------------+-------+------------+
|  1 | Processor Speed   | NULL  |          1 |
|  2 | RAM               | NULL  |          1 |
|  3 | Screen Resolution | NULL  |          1 |
|  4 | Screen Size       | NULL  |          1 |
|  5 | Battery Life      | NULL  |          1 |
+----+-------------------+-------+------------+



I can list the mappings if it would help. But, the fact that I am mutating the state of the attributes _before_ saving the parent to the DB and getting these results makes me think I just don't understand some base behavior. Why if I do the save prior to setting the attribute values, then again after, do I get the updates? Shouldn't it all happen on the first set of inserts?

John


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 4:45 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I think the problem is the strange Product.setProductType() method. You haven't shown the mapping documents, but I assume that this is also the method that Hibernate will call when setting the product type. And when Hibernate does this, every value on the attributes get reset to an empty string, I would first try to change this setter to be a "regular" setter, and then use a different method for the extra functionality you need. Eg:

Code:
public void setProductType(ProductType productType) {
   this.productType = productType;
}

public void setProductTypeExtended(ProductType productType) {
   setProductType(productType);
   for (AttributeDefinition definition : productType.getAttributeDefinitions()) {
      Attribute attribute = new Attribute();
      attribute.setName(definition.getName());
      attribute.setValue("");
      attributes.put(attribute.getName(), attribute);
      attribute.setProduct(this);         
   }
}


By the way, it is expected to be able to change the product type of a product? If you for example do as below, the 'attributes' collection will have entries for both product types.

Code:
product.setProductTypeExtended(laptopType);
product.setProductTypeExtended(dvdRecorderType);


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2009 5:05 am 
Newbie

Joined: Tue Jan 27, 2009 3:32 am
Posts: 4
Shit, I think you're absolutely right. Good catch. I will try it out tomorrow when I am back at the office. I hadn't gotten to preventing multiple product type attributes, but had anticipated it.

Thanks for your help and reading through my verbose post


Top
 Profile  
 
 Post subject: That was the problem
PostPosted: Tue Jan 27, 2009 2:19 pm 
Newbie

Joined: Tue Jan 27, 2009 3:32 am
Posts: 4
Thanks for the help nordborg


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.