Search code examples
javaspringhibernatebroadleaf-commerce

Persist product in broadleaf database


I am fetching products and categories from other source. I want to persist them in broadleaf database. I don't want auto generated ids. I want to persist id comes from source(from where I am fetching products etc.) to broadleaf database.

For that I have created my custom controller : http://www.broadleafcommerce.com/docs/core/current/broadleaf-concepts/admin/admin-custom-controllers

I am writing product and category persisting code in MyController.

I have tried following code :

    Category category =  catalogService.createCategory();
    Long categoryId = new Long(453510);
    category.setId(categoryId);
    category.setName("test category4");
    category.setUrl("/test-category4");

    catalogService.saveCategory(category);

    Product p =  catalogService.createProduct(ProductType.PRODUCT);

    Sku newSku = catalogService.createSku();
    Long skuId = new Long(453520);
    newSku.setId(skuId);
    p.setDefaultSku(newSku);
    p.getDefaultSku().setDefaultProduct(p);

    p.setName("test product4");
    p.setUrl("/test-product4");
    p.setCategory(category);
    Long productId = new Long(453530);
    p.setId(productId);
    catalogService.saveProduct(p);

I am getting following stacktrace :

Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "blc_sku" violates foreign key constraint "fk28e82cf77e555d75"
  Detail: Key (default_product_id)=(453530) is not present in table "blc_product".
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2182)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1911)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:173)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:645)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:495)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:441)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)

If I remove below snippet, then it gives me null pointer because product object required to set default sku.

Sku newSku = catalogService.createSku();
Long skuId = new Long(453520);
newSku.setId(skuId);
p.setDefaultSku(newSku);
p.getDefaultSku().setDefaultProduct(p);

Please help me to persist product with given id( not autogenerated) in broadleaf database.


Solution

  • Because Hibernate is configured to generate the values for the id attributes on these entities, Hibernate is forcing the next generated value even though you have attempted to override the value. It appears that your override value is being used for the foreign key and Hibernate's generated value is being set for the primary key resulting in the FK constraint violation.

    These entities (category, product, sku) have been designed with the assumption that users would be importing from external systems and because of that, they each have an externalId attribute defined. The recommended approach is to let Hibernate manage the pk/fk values via the generator and then the externalId attributes are used for mapping external systems into these entities.

    If your requirement does not allow the use of the externalId, you could look at trying to override the generator annotation on those attributes using load time weaving. There is no Broadleaf mechanism to override an existing annotation on an attribute so this would be a customization you would have to explore.