[hibernate-users] Hibernate - ManyToMany relationship w/ Shared key between Entities

Bruno Oliveira bruno.riev at gmail.com
Thu Aug 27 14:13:40 EDT 2015


I noticed that the Text-plain version of the email I sent may not be very
legible (w/o syntax highlighting).

So, in case somebody can help: here's the post I sent to SO:

http://stackoverflow.com/questions/32239156/hibernate-manytomany-relationship-w-shared-key-between-entities

Thank you.

On Thu, Aug 27, 2015 at 12:03 AM, Bruno Oliveira <bruno.riev at gmail.com>
wrote:

> Hello everyone!
>
> I'm having a pretty hard time in a not-so-usual (I guess?) scenario, that
> I'd like to ask your expertise for your enlightment.
>
> This one is kind of tricky, and I have looked up in, pretty much, all
> related questions in SO and forums, but I couldn't find an definitive
> answer. Let me get you the context:
>
> The scenario is the following:
>
>  Table: Product    Table: ProductCategory  Table: Category----------------|    ----------------|     |---------------|            | partner_Id    |    | product_Id    |     | partner_Id    | | product_Id    |    | category_Id   |     | category_Id   |         |---------------|    | partner_Id    |     |---------------|| name          |    |---------------|     | name          || description   |    | extra_fields  |     | description   || extra_fields  |    |               |     | extra_fields  ||---------------|    |---------------|     |---------------|
>
> And here are the classes:
>
> Product.java
>
> @Entity at Table(name = "EC_PRODUCT")public class Product implements Serializable {
>
>     private ProductPK productPK;
>     private List<ProductCategory> productCategories;
>     // Other Atributes
>
>     @Embeddable
>     public static class ProductPK implements Serializable {
>         private String partnerId;
>         private String productId;
>
>         public String getPartnerId() {
>             return this.partnerId;
>         }
>
>         public void setPartnerId(String partnerId) {
>             this.partnerId = partnerId;
>         }
>
>         public String getProductId() {
>             return this.productId;
>         }
>
>         public void setProductId(String productId) {
>             this.productId = productId;
>         }
>     }
>
>     public Product() {
>         this.productPK = new ProductPK();
>         this.productCategories = new ArrayList<ProductCategory>();
>     }
>
>     @Id
>     @AttributeOverrides({
>             @AttributeOverride(name = "partnerId", column = @Column(name = "partner_Id")),
>             @AttributeOverride(name = "productId", column = @Column(name = "product_Id"))
>     })
>
>     public ProductPK getProductPK() {
>         return this.productPK;
>     }
>
>     public void setProductPK(ProductPK productPK) {
>         this.productPK = productPK;
>     }
>
>     /*
>     ** Other Getters and Setters
>     */}
>
>
> Category.java
>
> @Entity at Table(name = "EC_CATEGORY")public class Category implements Serializable {
>
>     private CategoryPK categoryPK = new CategoryPK();
>     private List<ProductCategory> productCategories;
>     // Other Attributes
>
>     @Embeddable
>     public static class CategoryPK implements Serializable {
>         private String partnerId;
>         private String categoryId;
>
>         public String getPartnerId() {
>             return this.partnerId;
>         }
>
>         public void setPartnerId(String partnerId) {
>             this.partnerId = partnerId;
>         }
>
>         public String getCategoryId() {
>             return this.categoryId;
>         }
>
>         public void setCategoryId(String categoryId) {
>             this.categoryId = categoryId;
>         }
>     }
>
>     @Id
>     @AttributeOverrides({
>             @AttributeOverride(name = "partner_Id",  column = @Column(name = "partner_id")),
>             @AttributeOverride(name = "category_Id", column = @Column(name = "category_cod"))
>     })
>     public CategoryPK getCategoryPK() {
>         return this.categoryPK;
>     }
>
>     public void setCategoryPK(CategoryPK productPK) {
>         this.categoryPK = productPK;
>     }
>
>     @OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
>     public List<ProductCategory> getProductCategories() {
>         return this.productCategories;
>     }
>
>     public void setProductCategories(List<ProductCategory> productCategories) {
>         this.productCategories = productCategories;
>     }
>
>     /*
>     ** Other Getters and Setters
>     */
> }
>
>
> ProductCategory.java
>
> @Entity at Table(name = "EC_PRODUCT_CATEGORY")public class ProductCategory implements Serializable {
>
>     private Product product = new Product();
>     private Category category = new Category();
>
>     public ProductCategory() { }
>
>     public ProductCategory(Product product, Category category) {
>         this.setProduct(product);
>         this.setCategory(category);
>     }
>
>     @Id
>     @ManyToOne
>     @JoinColumns({@JoinColumn(name = "product_Id"), @JoinColumn(name = "partner_Id") })
>     public Product getProduct() {
>         return product;
>     }
>
>     public void setProduct(Product product) {
>         this.product = product;
>     }
>
>     @Id
>     @ManyToOne
>     @JoinColumns({@JoinColumn(name = "category_Id"), @JoinColumn(name = "partner_Id")})
>     public Category getCategory() {
>         return category;
>     }
>
>     public void setCategory(Category category) {
>         this.category = category;
>     }
> }
>
>
> And here's a Snippet of what my Main class does:
>
> public class App {
>
>    public static void main(String[] args) {
>
>         // Sets up the Product
>         Product product = new Product();
>         product.getProductPK().setPartnerId("1");
>         product.getProductPK().setProductId("99");
>
>         // Sets up the Category
>         Category category = new Category();
>         category.getCategoryPK().setPartnerId("1");
>         category.getCategoryPK().setCategoryId("10");
>
>         // Sets up the ProductCategory
>         product.getProductCategories().add(new ProductCategory(product, category));
>
>         // Data persistence w/ Hibernate
>         Session session = HibernateUtil.getSessionFactory().getCurrentSession();
>         session.beginTransaction();
>
>         session.save(product)
>
>         session.getTransaction().commit();
>         session.flush();
>         session.close();
>
>     }
> }
>
>
> And that's the stacktrace (I formated a bit to make it more legible):
>
> (...)Hibernate:
>
> select
>    productcat_.product_id,
>    productcat_.partner_id,
>    productcat_.category_id,
>    productcat_.partner_id
> from ECOM_STAGE_REL_CATEG_PROD productcat_
> where
>     productcat_.product_id=? and
>     productcat_.partner_id=? and
>     productcat_.category_id=? and
>     productcat_.partner_id=?
> Aug 26, 2015 9:53:25 PM org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl release
> INFO: HHH000010: On release of batch it still contained JDBC statements
> Aug 26, 2015 9:53:25 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
>
> WARN: SQL Error: 0, SQLState: S1009
> Aug 26, 2015 9:53:25 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
>
> ERROR: Parameter index out of range (4 > number of parameters, which is 3).
> org.hibernate.exception.GenericJDBCException: could not insert: [obscured_package_name.model.ProductCategory]
> Hibernate: insert into EC_PRODUCT_CATEGORY (product_id, partner_id, category_id) values (?, ?, ?)
>     at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
>     at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)(...)
>
> *Please notice that the 2nd and 4th line of the WHERE clause (in the
> SELECT statement) are the same*
>
> It's trying to get the partner_id for the Product (since its ProductPK
> is: productId, partnerId) AND the partner_id for the Category (since its
> CategoryPK is: categoryId, partnerId)
>
> It doesn't fail for the SELECT statement, because SQL-wise, it doesn't
> matter (but it does when it's doing an INSERT). And notice this at the end
> of the stack trace:
>
> ERROR: Parameter index out of range (4 > number of parameters, which is 3).
> org.hibernate.exception.GenericJDBCException: could not insert: [obscured_package_name.model.ProductCategory]
>
> Hibernate: insert into EC_PRODUCT_CATEGORY(product_id, partner_id, category_id) values (?, ?, ?)
>     at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
>
> It says It's trying to insert 4 FIELDs in a table that expects 3. (The
> only reason the INSERT statement has 3 fields -- which is supposedly
> correct -- is because "partner_id" is a common name between the Product and
> Category).
>
> IF, and ONLY IF, in ProductCategory.java, I were to rewrite the
> @JoinColumns in the getters, like this:
>
>  @Id
>     @ManyToOne
>     @JoinColumns({@JoinColumn(name = "product_Id"), @JoinColumn(name = "PRODUCT_partner_Id") })
>     public Product getProduct() {
>         return product;
>     }
>
>     @Id
>     @ManyToOne
>     @JoinColumns({@JoinColumn(name = "category_Id"), @JoinColumn(name = "CATEGORY_partner_Id")})
>     public Category getCategory() {
>         return category;
>     }
>
>
> The error would be like this:
>
> Hibernate: insert into EC_PRODUCT_CATEGORY(product_id, PRODUCT_partner_id, category_id, CATEGORY_partner_id) values (?, ?, ?, ?)
>     at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:54)
>
> Did I make it clear ?
>
> I tried to provide as much detail as possible, since it's tricky to
> understand. But I truly have searched everything I could and didn't come up
> with a solution.
>
> Please, may I have your advice/expertise on how to solve this ?
>
>
> Thank you very much in advance!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/hibernate-users/attachments/20150827/76c0fa27/attachment-0001.html 


More information about the hibernate-users mailing list