0

I have written a rest controller that receives a request and saves the data in db. This is my post request that I am trying to send using postman.

{
    "product_id" : "testproduct",
    "default_concurrent":10,
    "default_connections":1000,
    "msan":10
}

My entity class :

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;

import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Entity
@Table(name="products")
@EntityListeners(AuditingEntityListener.class)

public class Product {

    @Id
    @Column(name="product_id", nullable = false)
    private String product_id;

    @Column(name="default_concurrent", nullable = true)
    private int default_concurrent;

    @Column(name="default_connections", nullable = true)
    private int default_connections;

    @Column(name="msan", nullable = true)
    private int msan;



    public String getProduct() {
        return product_id;
    }

    public void setProduct(String product) {
        this.product_id = product;
    }

    public int getDefault_concurrent() {
        return default_concurrent;
    }

    public void setDefault_concurrent(int default_concurrent) {
        this.default_concurrent = default_concurrent;
    }

    public int getDefault_connections() {
        return default_connections;
    }

    public void setDefault_connections(int default_connections) {
        this.default_connections = default_connections;
    }

    public int getMsan() {
        return msan;
    }

    public void setMsan(int msan) {
        this.msan = msan;
    }


}

My Controller :

    @PostMapping("/add")
    public Product addProduct(@Valid @RequestBody Product product) 
    {
        return productDao.saveProduct(product);
    }

Error:

ids for this class must be manually assigned before calling save()
nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.test.model.Product",

I have gone through a lot of posts related to this error on SO, and most of them suggest to use

@GeneratedValue(strategy=GenerationType.AUTO) or @GeneratedValue(strategy=GenerationType.IDENTITY)

but I cant use it as my primary key is going to be string and I cant change it to Long.

While debugging I can see that in request body I am receiving product_id as null. Remaining attributes are having correct values.

But if I create one more column as 'Id' in the DB and update the Entity class accordingly making 'Id' as primary key and try to execute then I am getting the correct values in request body and it is getting saved in the DB as well.

Need help.

Naveen Yadav
  • 203
  • 9
  • 25

1 Answers1

1

Because we treat the underscore character as a reserved character, we strongly advise following standard Java naming conventions (that is, not using underscores in property names but using camel case instead).

Doc

The underscore _ is a reserved character in Spring Data query derivation to potentially allow manual property path description.

Stick to the Java naming conventions of using camel-case for member variable names and everything will work as expected.

You will also face an issue when using JPA Features. So I suggest that change the naming convention. Change

    private String product_id;
    private int default_concurrent;
    private int default_connections;
    private int msan;

To,

private String productId;
private int defaultConcurrent;
private int defaultConnections;
private int msan;

UPDATE1

Why only null for product_id

To find out that I have pasted the same code in my IDE and found that Entity Product is missing the getter-setter for field product_id. After adding it the same code is saving the values to the database. But I still recommend everyone to avoid the _ in names of the field to avoid the further issue and follow the naming convention as per doc. When using JPA, such as findBy(something with _ in name in an entity) you may face the issue similar to this

Romil Patel
  • 12,879
  • 7
  • 47
  • 76
  • Thanks Patel Romil, I was totally unaware of this fact!! – Naveen Yadav Jul 15 '19 at 08:58
  • Just one more doubt, I was getting null only for product_id but not for other fields like default_connections and default_concurrent even though they were also having underscore? – Naveen Yadav Jul 15 '19 at 09:00
  • Hello @NaveenYadav, I have pasted your code in IDE and found that your product model is missing getter-setter for product_id. without the getter-setter, it's producing the same issue as above but after I add this I am able to save it to database – Romil Patel Jul 15 '19 at 09:28
  • 1
    @NaveenYadav but I still recommend you to avoid _ in your field name as when you use JPA such as findBy(something) you may face an issue similar to https://stackoverflow.com/questions/56961166/findbyid-results-in-a-problem-error-no-property-id-found/56963362#56963362 – Romil Patel Jul 15 '19 at 09:30
  • okay now I got the issue.......and finally I can conclude underscore wasn't the actual culprit....It was the setter method that has to be "setProduct_id" instead of "setProduct" as suggested by @Jerry06 because I suppose internally it will be looking for former type setter. Thanks!!! – Naveen Yadav Jul 15 '19 at 09:40