-->
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: Help with Join Table Entity using Composite Id
PostPosted: Wed Mar 05, 2008 1:18 pm 
Newbie

Joined: Wed Mar 05, 2008 11:26 am
Posts: 8
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version:

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Problems with Session and transaction handling?

Read this: http://hibernate.org/42.html

I've read through the forums, and I've not been able to find the specific answer to my dilemma, so I'm hoping that someone can provide assistance (I'll admit that it's likely something simple that I'm missing here).

I have a single POJO that had a self-referencing many-to-many relationship that I needed to convert to allow for the inclusion of additional columns in my join table. I followed the example on pp. 302-303 of JP with Hibernate, but I'm unable to get it to work correctly.

The POJO:

Code:
@Entity
@Table(name = "Company")
public class Company
{
    @Id
    @GeneratedValue(strategy = SEQUENCE, generator = company_id_seq")
    @Column(name = "company_id")
    @NotNull
    private long                          companyId;

...

    @OneToMany(mappedBy = "accountCompany")
    private Collection<CompanyCompetitor> competitors;

    @OneToMany(mappedBy = "competitorCompany")
    private Collection<CompanyCompetitor> accounts;

...

//Original mapping:

    @ManyToMany
    @JoinTable(name = "Company_Competitor", joinColumns = @JoinColumn(name = "company_id"), inverseJoinColumns = @JoinColumn(name = "competitor_company_id"))
    private Collection<Company>            competitors;

    @ManyToMany
    @JoinTable(name = "Company_Competitor", joinColumns = @JoinColumn(name = "competitor_company_id"), inverseJoinColumns =  @JoinColumn(name = "company_id"))
    private Collection<Company>                accounts;


The new join-table entity is as follows:



Code:

@Entity
@Table(name = "Company_Competitor")
public class CompanyCompetitor
{
    @Embeddable
    public static class Id implements Serializable
    {
        private static final long serialVersionUID = 1L;

        @Column(name = "account_company_id")
        private Long accountCompanyId;

        @Column(name = "competitor_company_id")
        private Long competitorCompanyId;

        public Id()
        {           
        }

        public Id(Long accountCompanyId, Long competitorCompanyId)
        {
            this.accountCompanyId = accountCompanyId;
            this.competitorCompanyId = competitorCompanyId;
        }

        @Override
        public int hashCode()
        {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((accountCompanyId == null) ? 0 : accountCompanyId.hashCode());
            result = prime * result + ((competitorCompanyId == null) ? 0 : competitorCompanyId.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj)
        {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            final Id other = (Id) obj;
            if (accountCompanyId == null)
            {
                if (other.accountCompanyId != null) return false;
            }
            else if (!accountCompanyId.equals(other.accountCompanyId)) return false;
            if (competitorCompanyId == null)
            {
                if (other.competitorCompanyId != null) return false;
            }
            else if (!competitorCompanyId.equals(other.competitorCompanyId)) return false;
            return true;
        }
    }

    @EmbeddedId
    private Id      id = new Id();

    @ManyToOne
    @JoinColumn(name = "competitor_company_id", insertable = false, updatable = false)
    private Company competitorCompany;

    @ManyToOne
    @JoinColumn(name = "account_company_id", insertable = false, updatable = false)
    private Company accountCompany;

    @Column(name = "market_share")
    @Min(0)
    @Max(100)
    private Long    marketShare;

    public CompanyCompetitor()
    {
        this.id = new Id();
    }

    public CompanyCompetitor(Company competitor, Company accountCompany, long marketShare)
    {
        this.id.competitorCompanyId = competitor.getCompanyId();
        this.id.accountCompanyId = accountCompany.getCompanyId();

        competitor.getAccounts().add(this);
        accountCompany.getCompetitors().add(this);
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (marketShare ^ (marketShare >>> 32));
        result = prime * result + ((competitorCompany == null) ? 0 : competitorCompany.hashCode());
        result = prime * result + ((accountCompany == null) ? 0 : accountCompany.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final CompanyCompetitor other = (CompanyCompetitor) obj;
        if (marketShare != other.marketShare) return false;
        if (competitorCompany == null)
        {
            if (other.competitorCompany != null) return false;
        }
        else if (!competitorCompany.equals(other.competitorCompany)) return false;
        return true;
    }

    @Override
    public String toString()
    {
        return competitorCompany.getCompanyId() + "," + accountCompany.getCompanyId() + "," + marketShare;
    }

    public Company getCompetitorCompany()
    {
        if (competitorCompany == null) competitorCompany = new Company();
        return competitorCompany;
    }

    public void setCompetitorCompany(Company competitorCompany)
    {
        this.competitorCompany = competitorCompany;
    }

    public Company getAccountCompany()
    {
        if (accountCompany == null) accountCompany = new Company();
        return accountCompany;
    }

    public void setAccountCompany(Company accountCompany)
    {
        this.accountCompany = accountCompany;
    }

    public long getMarketShare()
    {
        if (marketShare == null) marketShare = (long) 0;
        return marketShare;
    }

    public void setMarketShare(long marketShare)
    {
        this.marketShare = marketShare;
    }

    public Id getId()
    {
        return id;
    }

    public void setId(Id id)
    {
        this.id = id;
    }
}




Any help would be appreciated... again, I'm sure it's something simple. With the previous many-to-many relationship, the join_table data was persisted when editing the core object (as it should), but now I'm not able to get the data to persist (despite the fact that it is coming back in from the user-inputs.


Top
 Profile  
 
 Post subject: Getting there, but still having some issues
PostPosted: Tue Apr 29, 2008 11:32 am 
Newbie

Joined: Wed Mar 05, 2008 11:26 am
Posts: 8
I'm managing to get this collection to properly save new entries, but I'm still having an issue with with updating or deleting entries in these collections. The problem is, in part, because the insert statements are issued prior to the update statement on the parent object. I've also noted that other collections using @CollectionOfElements are fully deleting entries prior to inserting the new instances, thereby ensuring the accuracy of the data matches that of the user's input.

So, my question is how to effectively remove deleted entries and update information in other entries.

Code:
Hibernate:
    select
        companymar_.account_company_id,
        companymar_.competitor_company_id,
        companymar_.market_share as market3_21_
    from
        Company_Market_Share companymar_
    where
        companymar_.account_company_id=?
        and companymar_.competitor_company_id=?
Hibernate:
    select
        companymar_.account_company_id,
        companymar_.competitor_company_id,
        companymar_.market_share as market3_21_
    from
        Company_Market_Share companymar_
    where
        companymar_.account_company_id=?
        and companymar_.competitor_company_id=?
Hibernate:
    select
        companymar_.account_company_id,
        companymar_.competitor_company_id,
        companymar_.market_share as market3_21_
    from
        Company_Market_Share companymar_
    where
        companymar_.account_company_id=?
        and companymar_.competitor_company_id=?
Hibernate:
    insert
    into
        Company_Market_Share
        (market_share, account_company_id, competitor_company_id)
    values
        (?, ?, ?)
Hibernate:
    update
        Company
    set


This is the SQL that is generated when updating this specific entity. When looking at other collections, the following occurs:

Code:

Hibernate:
    update
        Company
    set
        update_dttm=?,
        update_user_name=?,
        address1=?,
        address2=?,
        city=?,
        country=?,
        postal_code=?,
        state=?,
        alter_market_share=?,
        company_name=?,
        company_status_id=?,
        company_type_id=?,
        email=?,
        fax=?,
        notes=?,
        parent_company_id=?,
        phone=?,
        service_priority_id=?,
        url=?
    where
        company_id=?
Hibernate:
    delete
    from
        Company_Branch
    where
        company_id=?
Hibernate:
    delete
    from
        Company_Trader
    where
        company_id=?
Hibernate:
    insert
    into
        Company_Branch
        (company_id, branch)
    values
        (?, ?)
Hibernate:
    insert
    into
        Company_Trader
        (company_id, trader_id)
    values
        (?, ?)


At this point I'm completely hung up on this. Also, I'm not using any entity manager at this point, but rather a Spring simple form controller (working on migration to webflow) and a single call to saveObject(PK Id) within that specific DAO.

Any help would be MOST appreciated. Again, I'm REALLY stuck on this, and I've searched for days through the forums and have been unable to find any pertinent help...

Thanks,

AJ


Top
 Profile  
 
 Post subject: Update
PostPosted: Tue Apr 29, 2008 5:32 pm 
Newbie

Joined: Wed Mar 05, 2008 11:26 am
Posts: 8
I should also add that I tried to model this after the CaveatEmptor CategorizedItems object in the Java Persistence with Hibernate example. I've tried to include the CascadeType.DELETE_ORPHAN annotation, but everytime I do that I get the following error:

A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance:

Please, if anyone has any ideas, or if there is a message within the forums that might point me in the right direction, I'd really like to know...

AJ


Top
 Profile  
 
 Post subject: RESOLVED
PostPosted: Wed Apr 30, 2008 5:02 pm 
Newbie

Joined: Wed Mar 05, 2008 11:26 am
Posts: 8
I've taken an alternative route to this, as this was consuming far too much time and simply wasn't the most effective way to get this accomplished. I've created two objects, each with respective joins to the base object within a single join table. This allows for a "semi" bidirectional relationship, while enabling me to use the @CollectionOfElements annotation (with which I'm already familiar) to ensure persistence. While not ideal, this way does seem far simpler than using the single join table entity.

AJ


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.