1

I have been working on creating a composite key using hibernate. I found this link: how to make a composite primary key (java persistence annotation)

First of all I tried Tim's accepted solution with@NaturalId. Didn't work out for me.

Secondly, I tried Arthur Ronald F D Garcia's Solution. I am still having some problems with it. Here is my code which is very similar to the Arthur Ronald F D Garcia's Solution.

Mailbox class:

@Entity
public class Mailbox {

    @Id
    @GeneratedValue
    private int mailboxId;
    @Column( unique=true, nullable=false )
    private String name;    
    @Column( unique=true, nullable=false )
    private String employeeId;  
    private String status;
    private Date createdOn;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="joinedMailboxMessageId.mailboxId")
    private List<MailboxMessages> joinedMailboxMessageList = new ArrayList<MailboxMessages>();

    public Mailbox(){}
    public Mailbox(int id)  {this.mailboxId=id;}
    public void addSMail(SMail mail) {
        // Implementation
    }
    //Getters and setters
}

SMail class

@Entity
public class SMail {

    @Id
    @GeneratedValue
    private int messageId;

    private Date originDate;
    private String from;
    @ElementCollection
    private List<String> to=new ArrayList<String>();
    @Lob
    private String message;
    private String subject;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="joinedMailboxMessageId.messageId")
    private List<MailboxMessages> joinedMailboxMessageList = new ArrayList<MailboxMessages>();

    public SMail() {}
    public SMail(int messageId) {
        this.messageId=messageId;
    }

    // addMailbox sets up bidirectional relationship
    public void addMailbox(Mailbox mailbox) { // Implementation}
//Getters and setters
}

Finally my MailboxMessages class

@Entity
public class MailboxMessages {

    @ManyToOne
    @JoinColumn(name="MAILBOX_ID", insertable=false, updatable=false)
    private Mailbox mailboxId;

    @ManyToOne
    @JoinColumn(name="MESSAGE_ID", insertable=false, updatable=false)
    private SMail messageId;

    private boolean read;
    private boolean deleted;
    private boolean flagged;
    private String priority;
    private Date messageDate;

    @EmbeddedId
    // Implemented as static class - see bellow
    private MailboxMessagesId joinedMailboxMessageId;

    // INNER CLASS: required because this class contains composite id
    @Embeddable
    public static class MailboxMessagesId implements Serializable {

    @ManyToOne
        @JoinColumn(name="MAILBOX_ID")
        private Mailbox mailboxId;

        @ManyToOne
        @JoinColumn(name="MESSAGE_ID")
        private SMail messageId;

        // required no arg constructor
        public MailboxMessagesId() {}

        public MailboxMessagesId(Mailbox mailbox, SMail mail) {
            this.mailboxId = mailbox;
            this.messageId = mail;
        }

        public MailboxMessagesId(int mailboxId, int messageId) {
            this(new Mailbox(mailboxId), new SMail(messageId));
        }

        @Override
        public boolean equals(Object instance) {
            if (instance == null)
                return false;

            if (!(instance instanceof MailboxMessagesId))
                return false;

            final MailboxMessagesId other = (MailboxMessagesId) instance;

            if (!(mailboxId.getMailboxId()==(other.getMailboxId().getMailboxId())))
                return false;

            if (!(messageId.getMessageId()==(other.getMessageId().getMessageId())))
                return false;

            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 47 * hash + (this.mailboxId != null ? this.mailboxId.hashCode() : 0);
            hash = 47 * hash + (this.messageId != null ? this.messageId.hashCode() : 0);
            return hash;
        }

        //Getters and setters
    }
    //Constructors and getters and setters
}

Now the real problem is that hibernate is only creating table for mailbox class. So i guess the problem might be in other 2 classes. I tried the exact solution of Arthur Ronald; and it worked perfectly. Can you please help me identify the mistake I might be making in my code. And also if there is any alternative to this technique for creating composite key in MailboxMessage class

EDIT1:

One of the problem found is that i was using 'from' as my member field which is reserved keyword for sql. Who would have thought of that? But the problem still persists. Now i do have a table for smail class but still no table is created for MailboxMessages class. Please help me out.

Community
  • 1
  • 1
udit mittal
  • 529
  • 3
  • 14

2 Answers2

0

I think this is the solution for example fields names are just sample:

@Id
@Column(name = "EMP_NO_FK" , unique=true , nullable = false ,length=10)
private Long empno;

@Id
@Column(name = "GROUP_NO_FK" , unique=true , nullable = false ,length=5)
private Long  groupNo;

@Id
@Column(name = "DEPT_NO_FK" , unique=true , nullable = false ,length=10)
private Long deptno;

@Id
@Column(name = "YEAR_NAME_M_FK" , unique=true , nullable = false ,length=4)
private Integer  year;
abu taha9
  • 45
  • 14
  • I dont know about the primitive types but this solution surely dosent work for our own class types. I tried using the same approach first with and without using mapping constraints, but had to accept my defeat. – udit mittal Apr 14 '13 at 11:26
0

Found the solution myself: The problem were with using 'from' as data member in SMail class and 'read' as data member in MailboxMessages class as they are reserved keywords with mysql. Now all my tables are created not to mention with composite key. (Confirmed through database)

udit mittal
  • 529
  • 3
  • 14