-->
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: Issue loading / saving set
PostPosted: Tue May 16, 2006 4:59 pm 
Newbie

Joined: Tue May 16, 2006 4:26 pm
Posts: 5
I am having a strange, to me, error saving or loading a set. What I am doing works perfect with a different set of classes, but when I do it here I get a null value from getItems() , and new items don't get their fk set.

I am using the GenericDAO template pattern that was linked to from the wiki. It works great for all the other classes. These two work fine if I do them separately, but when I get the items for the invoice (after saving them separately and retrieving to a new object), the set is still null.

Hibernate version: 3
Mapping documents: Invoice.hbm.xml, InvoiceItem.hbm.xml
Code between sessionFactory.openSession() and session.close():
[ from a filter ]
sf.getCurrentSession().beginTransaction();
sf.getCurrentSession().setCacheMode(CacheMode.NORMAL);
sf.getCurrentSession().setFlushMode(FlushMode.COMMIT);
chain.doFilter() // my stuff
sf.getCurrentSession().getTransaction().commit();

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

The generated SQL (show_sql=true):
Code:
13:42:58,485 DEBUG SQL:346 - insert into invoice (user_id, status, ship_name, card_name, card_number, card_exp_year, card_exp_month, card_type, ship_address_id, bill_address_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
13:42:58,486 DEBUG LongType:79 - binding '2' to parameter: 1
13:42:58,489 DEBUG StringType:79 - binding 'WAITING' to parameter: 2
13:42:58,489 DEBUG StringType:79 - binding 'ShipName' to parameter: 3
13:42:58,494 DEBUG StringType:79 - binding 'CARD-NAME' to parameter: 4
13:42:58,494 DEBUG StringType:79 - binding 'CARD-NUMBER' to parameter: 5
13:42:58,495 DEBUG StringType:79 - binding '2008' to parameter: 6
13:42:58,495 DEBUG StringType:79 - binding '06' to parameter: 7
13:42:58,496 DEBUG StringType:79 - binding 'VISA' to parameter: 8
13:42:58,496 DEBUG LongType:79 - binding '21' to parameter: 9
13:42:58,497 DEBUG LongType:79 - binding '22' to parameter: 10
13:42:58,497 DEBUG LongType:79 - binding '4' to parameter: 11
13:42:58,499 DEBUG SQL:346 - insert into invoice_item (quantity, price, description, bouquet_id, invoice_id, item_id, id) values (?, ?, ?, ?, ?, ?, ?)
13:42:58,500 DEBUG LongType:79 - binding '3' to parameter: 1
13:42:58,501 DEBUG DoubleType:79 - binding '200.75' to parameter: 2
13:42:58,501 DEBUG StringType:79 - binding 'test item' to parameter: 3
13:42:58,508 DEBUG LongType:71 - binding null to parameter: 4
13:42:58,509 DEBUG LongType:71 - binding null to parameter: 5
13:42:58,510 DEBUG LongType:79 - binding '100' to parameter: 6
13:42:58,510 DEBUG LongType:79 - binding '2' to parameter: 7
13:42:58,535  WARN JDBCExceptionReporter:71 - SQL Error: 1048, SQLState: 23000
13:42:58,536 ERROR JDBCExceptionReporter:72 - Column 'invoice_id' cannot be null
13:42:58,539 ERROR AbstractFlushingEventListener:299 - Could not synchronize database state with session


The HBM files
Some of the simple proprites have been stripped out to shorten it up, but they all work. The many-to-ones work, putting items in the address table just like they should. I have left the invoice_id column on the invoice_items table nullable (in the hbm) so that you can see the error. If I don't do that, I get an error about not null property being set to null or transient.

Code:
<hibernate-mapping>
    <class name="model.Invoice" table="invoice" lazy="false">
        <id name="id" column="id" unsaved-value="null">
            <generator class="increment"/>
        </id>

        <property name="userId" column="user_id" not-null="true"/>
        <property name="status" column="status" not-null="true"/>
        ...
        <property name="dateCreated" column="date_created" insert="false" update="false" not-null="true"/>

        <many-to-one name="shipAddress" column="ship_address_id" lazy="false"
                     unique="true" cascade="all"
                />
        <many-to-one name="billAddress" column="bill_address_id" lazy="false"
                     unique="true" cascade="all"
                />

        <set name="items" lazy="true" inverse="true" cascade="all">
            <key column="invoice_id" />
            <one-to-many class="model.InvoiceItem"/>
        </set>
    </class>
</hibernate-mapping>
<hibernate-mapping>
    <class name="model.InvoiceItem" table="invoice_item" lazy="false">
        <id name="id" column="id" unsaved-value="null">
            <generator class="increment"/>
        </id>
        <property name="quantity"       column="quantity" not-null="true"/>
        <property name="price"          column="price"    not-null="true"/>
        <property name="description"    column="description" not-null="true"/>
        <property name="bouquetId"      column="bouquet_id" />
        <property name="invoiceId"      column="invoice_id"/>
        <property name="itemId"         column="item_id" not-null="false"/>
    </class>
</hibernate-mapping>


The Java
Code:
public class Invoice implements Serializable {

    private Long    id;
    private Long    userId;
    private double  total;
    private Date    dateCreated;
    private String  status;
    ...

    private Address shipAddress;
    private Address billAddress;

    private Set<InvoiceItem> items;

    public Invoice() {}

    // AUTOGENERATED ----------------------------------------
    public Long getId() {
        return id;
    }
   
    ....

public class InvoiceItem implements Serializable {

    private Long    id;
    private Long    invoiceId;
    private Long    bouquetId;
    private Long    itemId;
    private String  description;
    private long    quantity;
    private double  price;


    public InvoiceItem() {}

    //-- generate --------------

    public Long getId() {
        return id;
    }
   ...


The code that I am running
This is just some simple test code in a jsp.
Code:
    InvoiceDAO ivdao = DAOFactory.getInvoiceDAO();
    Invoice iv = new Invoice();
    iv.setUserId(2L);
    Address addr1 = new Address();
    Address addr2 = new Address();
    addr1.setStreet("one place");
    addr1.setCity("san anselmo");
    addr1.setState("CA");
    addr1.setZip("11111");
    addr2.setStreet("wtf street");
    addr2.setCity("san Rafael");
    addr2.setState("FR");
    addr2.setZip("doh");

    iv.setShipName("ShipName");
    iv.setStatus("WAITING");
    iv.setTotal(0);
    iv.setShipAddress(addr1);
    iv.setBillAddress(addr2);

    InvoiceItem itm = new InvoiceItem();
    itm.setDescription("test item");
    itm.setItemId(100L);
    itm.setPrice(200.75);
    itm.setQuantity(3);
    itm.setInvoiceId(iv.getId());
    HashSet<InvoiceItem> set = new HashSet<InvoiceItem>();
    set.add(itm);
    iv.setItems(set);
    ivdao.makePersistent(iv);


Any clues as to why this is happening. it is driving me completely mad. I assume there is some fundamental problem that exists but that hibernate is not telling me about (like long vs. Long) that makes this not work.

Thanks,
Andrew Backer


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 16, 2006 7:07 pm 
Regular
Regular

Joined: Fri Oct 01, 2004 2:19 am
Posts: 111
Location: Melbourne, Australia
Your'e specifying the set element with inverse=true, yet there's no relationship
(as far as Hibernate is concerned) connecting InvoiceItem back to Invoice
(the InvoiceId member is just that - a member). You will need to set the
invoiceId member as a <many-to-one> for hibernat to pick it up.

Have a look at the Hibernate reference documentation, Chapter 22. It has
a lot of good information about mapping these types of entities.

_________________
Cheers,

Bonny

please don't forget to rate :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 16, 2006 10:50 pm 
Newbie

Joined: Tue May 16, 2006 4:26 pm
Posts: 5
Thanks for the idea, I gave it a shot again. I have tried inverse="false", and just about every other option. I have put in object accessors into the invoice item class/hbm even though I do not need them. I have changed cascade options, followed samples from other areas, etc.

setting inverse="false" does not fix it
adding a "many-to-one" to the items table does not fix it.
inserting a record manually and then trying to pull our the invoice still results in an empty set.

However, here is the problem I have with every hibernate example in the documentation that makes them difficult to use.

The column names are the same in every table.
This makes it difficult to tell what table [blog_id] refers to in the mappings. Since the property is always named 'column' and not something like "foreign-column" or "local-column" it is confuzing.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 16, 2006 11:41 pm 
Expert
Expert

Joined: Tue Apr 25, 2006 12:04 pm
Posts: 260
Code:
<hibernate-mapping>
    <class name="model.Invoice" table="invoice" lazy="false">
        <id name="id" column="id" unsaved-value="null">
            <generator class="increment"/>
        </id>

        <property name="userId" column="user_id" not-null="true"/>
        <property name="status" column="status" not-null="true"/>
        ...
        <property name="dateCreated" column="date_created" insert="false" update="false" not-null="true"/>

        <many-to-one name="shipAddress" column="ship_address_id" lazy="false"
                     unique="true" cascade="all"
                />
        <many-to-one name="billAddress" column="bill_address_id" lazy="false"
                     unique="true" cascade="all"
                />

        <set name="items" lazy="true" inverse="true" cascade="all-delete-orphan">
            <key column="id" />
            <one-to-many class="model.InvoiceItem"/>
        </set>
    </class>
</hibernate-mapping>



observe here, I have element many-to-one on column invoice_id which I am assuming is primary key "id" in invoice table.
Code:
<hibernate-mapping>
    <class name="model.InvoiceItem" table="invoice_item" lazy="false">
        <id name="id" column="id" unsaved-value="null">
            <generator class="increment"/>
        </id>
        <property name="quantity"       column="quantity" not-null="true"/>
        <property name="price"          column="price"    not-null="true"/>
        <property name="description"    column="description" not-null="true"/>
        <property name="bouquetId"      column="bouquet_id" />
        <property name="invoiceId"      column="invoice_id"/>
        <property name="itemId"         column="item_id" not-null="false"/>

   <many-to-one name="invoiceObject" class="model.Invoice" column="invoice_id" insert="false" update="false"/>
    </class>
</hibernate-mapping>



Code:
public class InvoiceItem implements Serializable {

    private Long    id;
    private Long    invoiceId;
    private Long    bouquetId;
    private Long    itemId;
    private String  description;
    private long    quantity;
    private double  price;

    private Invoice invoiceObject;


    public InvoiceItem() {}

    //-- generate --------------

    public Long getId() {
        return id;
    }
   ...


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.