-->
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.  [ 6 posts ] 
Author Message
 Post subject: [SOLVED] Primary Key field: "doesn't have a default val
PostPosted: Mon Jul 28, 2008 9:25 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
I've been scratching my head on this one and I'm not sure Hibernate won't play nice with MySQL. I am getting the following error:

Code:
java.sql.SQLException: Field 'member_id' doesn't have a default value
... (and many more parts of the stack trace)


I've tried:
- @GeneratedValue(strategy = AUTO)
- @GeneratedValue(strategy = ENTITY)
- @GeneratedValue
- [no reference to GeneratedValue at all]

But I still get:

Code:
java.sql.SQLException: Field 'member_id' doesn't have a default value


The MySQL DB has the following table:
Code:
+-----------------+-------------+------+-----+---------+----------------+
| Field           | Type        | Null | Key | Default | Extra          |
+-----------------+-------------+------+-----+---------+----------------+
| member_id       | int(10)     | NO   | PRI | NULL    | auto_increment |
| lastname        | varchar(20) | NO   |     |         |                |
| firstname       | varchar(20) | NO   |     |         |                |
| onlinename      | varchar(20) | NO   |     |         |                |
| password        | varchar(15) | NO   |     |         |                |
| url             | varchar(50) | YES  |     | NULL    |                |
| membersince     | date        | NO   |     |         |                |
| email           | varchar(40) | NO   |     |         |                |
+-----------------+-------------+------+-----+---------+----------------+


The Member class representing this table is:
Code:
@Entity
@Name("member")
@Table(name="member")
public class Member implements Serializable {

    private static final long serialVersionUID = 1881413500711441951L;
    private int memberID;
    private String lastName;
    private String firstName;
    private String onlineName;
    private String password;
    private String emailAddress;
    private String url;
    private Date memberSince;
    private OnlineAccount onlineAccount;
    private MemberAddress memberAddress;
...
    @Id @GeneratedValue(strategy = AUTO)
    @Column(name = "member_id")
    public int getMemberID() {
        return memberID;
    }
    @OneToOne(optional = true, cascade = ALL, fetch = EAGER)
    @JoinColumn(name="memberaddress_id")
    public MemberAddress getMemberAddress()
    {
        return memberAddress;
    }
    @OneToOne(optional = false, cascade = ALL)
    @JoinColumn(name="onlineaccount_id")
    public OnlineAccount getOnlineAccount()
    {
        return onlineAccount;
    }
}


Member has two one-to-one relationships with the following weak entities:

MemberAddress.java (which is optional - see below annotation):

Code:
@Entity
@Name("memberaddress")
@Table(name="memberaddress")
public class MemberAddress {

    private String mailingAddress;
    private String stateOrProvince;
    private String zipOrpostalCode;
    private long memberAddressID;
    private Member owner;
    public MemberAddress(Member owner)
    {
        this.owner = owner;
    }

    public void setOwner(Member owner)
    {
        this.owner = owner;
    }
    @Id @GeneratedValue(strategy = AUTO)
    @Column(name = "memberaddress_id")
    public long getMemberAddressID() {
        return memberAddressID;
    }
}


And finally the OnlineAccount.java class (which is not optional):

Code:
@Entity
@Name("onlineaccount")
@Table(name="onlineaccount")
public class OnlineAccount
{

    private long onlineAccountID;
    private String companyName;
    private String accountNumber;
    private Member owner;

    public void setOwner(Member owner)
    {
        this.owner = owner;
    }

    @OneToOne(mappedBy = "onlineAccount")
    public Member getOwner()
    {
        return owner;
    }

    @Id @GeneratedValue(strategy = AUTO)
    @Column(name = "onlineaccount_id")
    public long getOnlineAccountID() {
        return onlineAccountID;
    }
}


Not sure why Hibernate won't pick up on the fact that I want MySQL to generate this since that's what the annotations are suggesting. Anyone have an idea what I'm doing wrong?

Btw, I'm using Seam 2.02, Hibernate 3.2.4.sp1, Tomcat 6, MySQL 5. Any help appreciated.

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Last edited by Arron.Ferguson on Tue Jul 29, 2008 8:58 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 7:32 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
What about changing the default value to something other than null?

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 8:02 am 
Regular
Regular

Joined: Wed Jan 11, 2006 12:49 pm
Posts: 64
Location: Campinas, Brazil
MySQL 5 + @GeneratedValue(AUTO) will require a autoinc column for the @Id property. If you let Hibernate create the tables for you, it will do this. Since you have shown that the column really is not autoinc, I am assuming you created it yourself or did not drop the table between changes of generation strategy.

It also seems that your OnlineAccount entity may be (or become) cause of some more trouble. You see, in a one-to-one mapping, you should make the relationship attribute also the ID of the entity, therefore ensuring the relationship consistency.

Code:
@Entity
@Name("onlineaccount")
@Table(name="onlineaccount")
public class OnlineAccount
{
    // ...
    @Id
    @OneToOne(mappedBy = "onlineAccount")
    public Member getOwner()
    {
        return owner;
    }

    // remove onlineAccountID or give it another meaning by not making it a
    // generated value
}

Also make sure that the direction of the one-to-one property is OK. As far as I remember, the relationship owner should be OnlineAccount:

Code:
@Entity
@Name("onlineaccount")
@Table(name="onlineaccount")
public class OnlineAccount
{
    // ...
    @Id
    @OneToOne
    @JoinColumn(name = "owner_id")
    public Member getOwner()
    {
        return owner;
    }

    // remove onlineAccountID or give it another meaning by not making it a
    // generated value
}

@Entity
@Name("member")
@Table(name="member")
public class Member implements Serializable {
    // ...
    @OneToOne(optional = true, cascade = ALL, fetch = EAGER, mappedBy = "owner")
    public MemberAddress getMemberAddress()
    {
        return memberAddress;
    }
    // ...
}

// the same goes for memberAddress

Finally, to make Member implement Serializable correctly you should make MemberAddress and OnlineAccount implement Serializable too.

My main hint to you is: let Hibernate generate the tables (maybe in another schema so that you do not have to drop your tables) and see if anything that you did not plan comes up. As I use to say to my co-workers, the program is only doing what you programmed it to do.

Best regards,

Henrique

_________________
Henrique Sousa
Don't forget to rate useful responses


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 4:04 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
Henrique,

Thanks for your response. You were correct about generating the tables outside of Hibernate. I didn't realize that Hibernate would do it for me :)

Also, you were correct in pointing out a bad design choice I had made which was to have the weak entity contain its own primary key. The weak entity should share (i.e., it's primary key is the foreign key of the parent/owner entity).

I did try your solution as well as the two other solutions:

Sun's Javadocs on the OneToOne annotation, specifically example 2: One-to-one association that assumes both the source and target share the same primary key values:
http://java.sun.com/javaee/5/docs/api/javax/persistence/OneToOne.html

I also tried an example from a Hibernate forum post at:
http://forum.hibernate.org/viewtopic.ph ... beb438a433

Entitled "Best way to map @OneToOne association with generated keys". Unfortunately all three examples generate the same error for me which is:

Code:
javax.persistence.PersistenceException: org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne: OnlineAccount.owner in mappedBy of Member.onlineAccount


I have made sure that the DB has been cleared out (i.e., all tables generated by Power Architect have been removed) so that Hibernate can create the tables instead and thus make autoinc choices on its own. I don't suppose you've come across this particular error. Either way, thank you kindly for responding - you caught two errors on my part. :)

Arron

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 8:57 pm 
Newbie

Joined: Fri Jul 25, 2008 5:22 am
Posts: 12
Got it! The following link allowed me to create a bidirectional one-to-one association with the weak entity using the parent/strong entity's primary key. The following link has the example:

http://tadtech.blogspot.com/2007/09/hib ... imary.html

Having said that Henrique, you pointed me in the right direction and gave me some really good feedback so we'll say that your answer was what solved this. Thanks again Henrique.

:)

Arron

_________________
“The Edge... there is no honest way to explain it because the only people who really know where it is are the ones who have gone over.” - Hunter S. Thompson


Top
 Profile  
 
 Post subject: Re: [SOLVED] Primary Key field: "doesn't have a default val
PostPosted: Tue Jun 16, 2009 11:01 am 
Newbie

Joined: Thu Apr 02, 2009 9:47 am
Posts: 2
Hi Arron,

It seem that you solved your problem.
I try to implement example in http://tadtech.blogspot.com but it didn't work.

If you still keep the code, pleqse show me :)

Thanks


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