Search code examples
hibernatespring-data-jpahibernate-mapping

Hibernate ManyToOne syntax


I'm trying to make a code to using MSSQL + Hibernate/JPA where I could entry some products and make a FK on it referring to a company.

my relation is that way

    @OneToMany(mappedBy = "companyId")
    private Set<Product> product;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "companyId")
    private Company companyId;

But rather then take the FK that I send in my JSON it creates a new company

This is the JSON:

{
    "name":"Test",
    "price":"35.63",
    "productCompanyId":"10293", (this is the ID on company receipt, to make )
    "companyId":"2"
}

here my entities

@Data
@Entity
@Table
@NoArgsConstructor
@AllArgsConstructor
public class Company {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;

    @NotNull
    String name;

    @OneToMany(mappedBy = "companyId")
    private Set<Product> product;

    public Company(String name){
        this.name = name;
    }
}
@Data
@Entity
@Table
@NoArgsConstructor
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @NotNull
    int productCompanyId; //product code in company receipt, making easier later updates

    @NotNull
    String name;

    @NotNull
    java.math.BigDecimal price;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "companyId")
    private Company companyId;// identification of where it was purchased

    public Product(String name, java.math.BigDecimal price, int productCompanyId, Company companyId) {

        this.price = price;
        this.name = name;
        this.productCompanyId = productCompanyId;
        this.companyId = companyId;
    }

}

Database: [1]: https://i.sstatic.net/WtRWR.jpg

id  name
1   TestCompany1
2   TestCompany2
3   2
id  name    price   product_company_id  company_id
1   Test    35.63   10293   3

I Think the problem is here:

@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    ProductRepository productRepository;

    @PostMapping
    public ResponseEntity<Product> insertProduct (@RequestBody ProductForm form){
        Product product = form.creationConverter();
        productRepository.save(product);
        return ResponseEntity.ok().build();
    }
}

@Data
public class ProductForm {

    @NotNull
    String name;

    @NotNull
    java.math.BigDecimal price;

    @NotNull
    int productCompanyId;

    @NotNull
    Company companyId;

    public Product creationConverter() {
        return new Product(name, price, productCompanyId, companyId);
    }

    public Product updateConverter(Integer id, ProductRepository productRepository) {
        Product product = productRepository.getOne(id);
        product.setName(this.name);
        product.setPrice(this.price);
        product.setProductCompanyId(this.productCompanyId);
        product.setCompanyId(companyId);
        return product;
    }
}

But I can't find a way to set this companyId to int (I'm sending a new objetc to controller, it's expected the creation of new company instead of just linking it)


Solution

  • after some tests and reading a lot of stuff I find the problem isn't my relation. But my ProductForm.java

    What I did to fix it is a quite simple in fact. First I remove my @ManyToOne relation, because it force me to create a Company variable in my Product Leaving only @OneToMany in company. It this way I could use a int variable "companyId" in my product and the records in database stops to duplicate =)

    This is how worked:

    Product:

    @Data
    @Entity
    @Table
    @NoArgsConstructor
    public class Product {
    
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        @NotNull
        int productCompanyId; //product code in company receipt, making easier later updates
    
        @NotNull
        String name;
    
        @NotNull
        java.math.BigDecimal price;
    
        @NotNull
        int companyId;// identification of where it was purchased
    
        public Product(String name, java.math.BigDecimal price, int productCompanyId, int companyId) {
    
            this.price = price;
            this.name = name;
            this.productCompanyId = productCompanyId;
            this.companyId = companyId;
        }
    
    }
    

    ProductForm:

    @Data
    public class ProductForm {
    
        @NotNull
        String name;
    
        @NotNull
        java.math.BigDecimal price;
    
        @NotNull
        int productCompanyId;
    
        @NotNull
        int companyId;
    
        public Product creationConverter() {
            return new Product(name, price, productCompanyId, companyId);
        }
    
        public Product updateConverter(Integer id, ProductRepository productRepository) {
            Product product = productRepository.getOne(id);
            product.setName(this.name);
            product.setPrice(this.price);
            product.setProductCompanyId(this.productCompanyId);
            product.setCompanyId(companyId);
            return product;
        }
    }
    

    And then the company with the relation:

    @Data
    @Entity
    @Table
    @NoArgsConstructor
    @AllArgsConstructor
    public class Company {
    
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        int id;
    
        @NotNull
        String name;
    
        @OneToMany(mappedBy = "companyId")
        private Set<Product> product;
    
        public Company(String name){
            this.name = name;
        }
    }