Column 'brand_id' cannot be null - java

I create new Product using Spring Boot / Hibernate / JPA and get Column 'brand_id' cannot be null error. I don't know why this error happen. Does anyone can explain where I was wrong?
Product:
#Entity
public class Product {
#javax.persistence.Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
#NotBlank(message = "Product name is required")
private String name;
private String image;
private String description;
private double price;
private int countInStock;
private double rating;
private int numReviews;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "brand_id", updatable = false, nullable = false)
#JsonIgnore
private Brand brand;
#ManyToMany
#JoinTable(name = "product_category", joinColumns = #JoinColumn(name = "product_id"), inverseJoinColumns = #JoinColumn(name = "category_id"))
#JsonIgnore
private List<Category> categories;
Brand:
#Entity
public class Brand {
#javax.persistence.Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
#NotBlank(message = "Brand name is required")
private String name;
#OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "brand", orphanRemoval = true)
private List<Product> products;
Category:
#Entity
public class Category {
#javax.persistence.Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
#NotBlank(message = "Category name is required")
private String name;
#ManyToMany(mappedBy = "categories")
private List<Product> products;
And my Product Object that used to input create new Product:
{
"name": "test",
"image": "/images/test.jpg",
"description": "test",
"brand_id": 4,
"category_id": 1,
"price": 99.99,
"countInStock": 100,
"rating": 4.5,
"numReviews": 120
}

Wherever you are creating this Product object, you must provide it with a Brand object.
Currently, you are only providing it with an integer as a Brand.
What you need to do is fetch the brand object you are referring to from your DB and include it in the instantiation of your new Product.
Probably the best and simplest approach to this would be using the EntityManager to get a reference to that Brand.
Getting the EntityManager is very simple when using spring.
#PersistenceContext
private EntityManager entityManager;
Now, simply use it to get the reference to the target Brand.
Brand brand = entityManager.getReference(Brand.class , brand_id);
Use this brand to instantiate your new Product and insert it to the DB without any exceptions.
How to automate this logic into the unmarshalling process
If you are always going to want to use this logic when creating a Product, you can use this logic in the constructor. If you only want to use this method when unmarshalling, here is an example that is based of something I wrote recently. I am using an XmlAdapter, but there are also JSONAdapater classes you can look into and should work about the same way.
Create you adapter class. This class is going to be used to parse JSON to java object.
//Once again, I am using an XmlAdapter, but the idea should be similar with JSONAdapters
#Service
public class BrandIdXmlAdapter extends XmlAdapter<String, Brand> {
#PersistenceContext
private EntityManager entityManager;
//v is the String that is going to be unmarshalled.
//In our case, its going to be the brand_id String.
#Override
public Brand unmarshal(String v) {
Brand brand = entityManager.getReference(Brand.class, v);
return brand;
}
There is also a possibility to override the marshal() method for parsing from a POJO to XML/JSON.
The only problem here is that to be able to use use the PersistenceContext annotation, this class has to be an EJB.
We are going to workaround that by telling Spring this is a necessary service.
First step is to give the adapter class the Service annotation(Done in example above).
The next step is to go to where you would want to unmarshall the input into a POJO (either the controller if you receive it as a request or the service if you are going to request it from another service) and autowire the adapter
#Autowired
private BrandIdXmlAdapter xmlAdapter;
Next step is to create the unmarshaller that will use this adapter.
JAXBContext context = JAXBContext.newInstance(Product.class);
brandIdUnmarshaller = context.createUnmarshaller();
brandIdUnmarshaller.setAdapter(xmlAdapter);
Now when receiving the data, use the brandIdUnmarshaller.unmarhsall() method.
Last step is to annotate your Brand variable in Product to tell it to use the adapter when parsing this specific variable.
public class Product {
.
.
.
//again, find the right annotation according to your JSONAdapter
#XmlJavaTypeAdapter(BrandIdXmlAdapter.class)
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "brand_id", updatable = false, nullable = false)
#JsonIgnore
private Brand brand;
}
Now everytime you parse from JSON to Product, you will automatically get a Product that contains a valid Brand object.

Related

How to update Child entity along with Parent entity in Spring Boot?

I am trying to update the parent entity and child entity (comes with parent) using JPA. I tried many ways but I couldn't do it. It gives me the following error.
javax.persistence.EntityExistsException: A different object with the
same identifier value was already associated with the session Contact(6)
Following is the entity,
Parent -> User.java
#Entity
public class User extends Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_generator")
#SequenceGenerator(name = "seq_generator", sequenceName = "seq_users", initialValue = 1, allocationSize = 1)
private Long id;
private String firstName;
private String lastName;
private String email;
private String password;
private String street;
private String city;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "userContact")
private Contact contact;
}
Child -> Contact.java
#Entity
public class Contact extends Serializable {
private static final long serialVersionUID = 1L;
#Getter(value = AccessLevel.NONE)
#Setter(value = AccessLevel.NONE)
#Id
#Column(insertable = false, updatable = false)
private Long id;
#MapsId
#OneToOne
#JoinColumn(name = "id", nullable = false)
private User userContact;
private String phone;
}
In my Service.java I am updating like this,
#Override
#Transactional
public User update(Long id, User user) {
Optional<User> curUser = userRepo.findById(id);
user.setId(curUser.get().getId());
user.setStreet(curUser.get().getStreet());
user.setCity(curUser.get().getCity());
Contact contact = user.getContact();
contact.setUserContact(user);
user.setContact(contact);
return userRepo.save(user);
}
And the update JSON payload is like this,
{
"firstName": "FirstName",
"lastName": "LastName",
"email": "Email",
"password": "Password",
"contact": {
"phone": "0123456789"
}
}
So why I can't update this at once? The insert is working fine but this update is not working. What I am doing wrong here? I really appreciate it if anybody can help me. Thanks in advance.
Here is the new way I tried,
#Override
#Transactional
public User update(Long id, User user) {
Optional<User> curUser = userRepo.findById(id);
curUser.setFirstName(user.getFirstName());
curUser.setlastName(user.getLastName());
curUser.setEmail(user.getEmail());
curUser.setPassword(user.getPassword());
Contact contact = user.getContact();
contact.setUserContact(curUser);
curUser.setContact(contact);
return userRepo.save(curUser);
}
Because you have the same user (i.e. same id) represented twice in the persistence context.
This line loads the user curUser in the persistence context.
Optional<User> curUser = userRepo.findById(id);
This line makes user the same user by id, but it is a different instant.
user.setId(curUser.get().getId());
And finally this line tries to add user to the persistence context.
userRepo.save(user);
This would result with the two instances being attached to the persistence context while representing the same user with the same id which would result in an inconsistent state since JPA wouldn't know which version to persist. Therefore this is forbidden and throws the exception you are seeing.
In your case changing
Optional<User> curUser = userRepo.findById(id);
user.setId(curUser.get().getId());
to
user.setId(id);
should do the trick.
Regarding your comments:
The same problem exists for referenced objects. You'll have to make sure that you: either load an entity and change it's attribute, or do NOT load the entity, not directly nor indirectly via a reference and save a detached entity, constructed from your request.
If you load an entity and then try to save a detached instance of it, you will get this kind of error.

One to Many Json Reponse With Jackson is not Working

I have a problem using JPA and RelationsShips One to Many with Jackson and Spring Rest ... I try to find multiples solutions but anything is working for me , and I don't kno where is the problem.
For example I have a table Team that has One to Many/Many To One relationship
I have two repository one for Team and another for Player
Team >>> has Many >> Player
Player >>> many to one >> Team
My entity Team has the following content
#Entity
#Table(name = "teams")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Team {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private long teamId;
private String abbreviation;
private String team;
private String simpleName;
private String logo;
#OneToMany(cascade = {CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE}, mappedBy = "team")
#Column(nullable = false)
private List<Player> players;
Theirs getters/setter , hashcodes and string similars.
On the other hand the entity Player
#Entity
#Table(name = "player")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Player {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private long id;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "teams_id", nullable=true)
private Team team;
private String name;
So , I have the typical get call in a controller in a repository.
#RestController
#RequestMapping("/api/public/team")
public class TeamController {
#Autowired
private TeamRepository teamRepository;
#Autowired
private GenericMethods genericMethods;
#GetMapping(value = "/{id}")
public Team getPersona(#PathVariable("id") int id) {
return teamRepository.findOne(genericMethods.toLong(id));
}
And repository
#Repository
public interface TeamRepository extends JpaRepository<Team, Long> {
}
Now , when I call this endpoint I receive the following answer and I think that is incorrect , I only need a List With Players
{
"id":2,
"teamId":0,
"abbreviation":null,
"team":null,
"simpleName":"Betis",
"logo":null,
"players":[
{
"id":1,
"team":2,
"category":{
"id":1,
"nombre":"juvenil a",
"language":null,
"description":null,
"league":[
],
"players":[
1,
{
"id":2,
"team":2,
"category":1,
"name":"hulio"
}
]
},
"name":"pepe"
},
2
]
}
I need to acces at information with Player and Team so I can't use #JsonIgnoreProperties
Could anyone help to solve this problem ?
Depending on what you really want to achieve you may try different options. I'm not sure if you're using (or intending to use) spring-data-rest or not.
1. Dedicated repository
Spring data rest will embed the related entities if they don't have their own repository. Try creating public interface PlayersRepository extends JpaRepository...
2. Lazy loading
Why are you using FetchType.EAGER ? Try without it.
3. Projections
Projections are only applicable to lists, not to individual entities (i.e. not explicitly what you're asking for). You can hide players from the Teams collection even if it was returned by default like so:
#Projection(name = "noPlayers", types = { Team.class })
public interface TeamWithoutPlayers {
Long getId();
long getTeamId();
String getAbbreviation();
String getTeam();
String getSimpleName();
String getLogo();
}
More info - Spring Data Rest Projections
4. Ignore during serialization in Team Entity using #JsonIgnore
#JsonIgnore
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "teams_id", nullable=true)
private Team team;
Final thought
With spring-data-rest you can extend a CrudRepository instead of JpaRepository and access the item directly through the repository. That way you don't need to write a controller.

CRUD issue reading a JSON using POST method in a REST API in Java using Jersey from a ManyToMany noted in hibernate

So, my problem goes like this: I created a RESTfull web service in Java using Jersey. Also, to map and use the MySQL database, I used hibernate (jpa).
I have a POJO named "horarios". Also, a POJO named "turmas". They are refered to each other using a #ManyToMany notaion in Hibernate. They go as this:
Turmas.java
#Entity
public class Turmas {
#Id
#GeneratedValue
#Column(name = "turmas_id", unique = true, nullable = false)
int Id;
#Column
String codigo;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "turmas_horarios", joinColumns = {
#JoinColumn(name = "turmas_id", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "horarios_id",nullable = false, updatable = false) })
private List<horarios> Horarios;
}
//... getters and setters
Horarios.java
#Entity
public class horarios {
#Id
#GeneratedValue
#Column(name = "horarios_id", nullable = false, unique = true)
int Id;
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "Horarios")
private List<Turmas> turmas;
#Column
private int horario;
#Column
private int dia;
//...getters and setters
}
And here goes the HorariosController:
#Path("/horarios")
public class HorariosController {
#Path("/setHorarios")
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response setHorarios(horarios h) throws Exception
{
horarios h1 = new horarios();
h1.setDia(h.getDia());
h1.setHorario(h.getHorario());
h1.setTurmas(h.getTurmas());
Querys.Persist(h1);
return Response.status(200).build();
}
}
//...GET and DELETE methods
The problem goes like this: For every column, it is very easy to treat the json object. But I really can't do it using a many to many type.. here goes an example of a json I'm sending:
{"dia": 6,"horario": 15,"turmas": {"codigo":"xxxx"}}
Which is valid according to http://www.jsonlint.com/. Though, when I try the POST method, it gives me the return:
Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream#1b23d8c; line: 3, column: 15] (through reference chain: modules.horarios["turmas"])
And for that reason I can't extract the value I put in the Turmas' fields.
The final question is: How (and what do I have to change) to read the JSON file and put in the Join Column the relationship between a passed Turmas and Horarios?
Like how can I read the turmas' passed Id (for example) without getting that error?
you have to change your json like below. As per your horaio entity definition your horario should have list of turmas.
{"dia": 6,"horario": 15,"turmas": [{"codigo":"xxxx"}]}

Hibernate and JSON - is there a definitive solution to circular dependencies?

I'm struggling with Hibernate entities and JSON in these days and, although there is a lot of questions regarding the object, I'm yet not capable to serialize in presence of circular dependencies. I tried with both Gson and jackson but I didn't get a lot of progresses.
Here is an excerpt from my objects.
This is the "parent" class.
#Entity
public class User extends RecognizedServerEntities implements java.io.Serializable
{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "user", orphanRemoval = false)
#Cascade({CascadeType.SAVE_UPDATE})
private Set<Thread> threads = new HashSet<Thread>(0);
//...other attributes, getters and setters
}
and this is the "children" class
#Entity
#Table(name = "thread")
public class Thread extends RecognizedServerEntities implements java.io.Serializable
{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "author", nullable = true)
private User user;
//...other attributes, getters and setters
}
I've written a simple class to test both gson and jackson features; as said, they both raise an exception.
public class MyJsonsTest
{
private static User u;
public static void main(String[] args)
{
u = new User("mail", "password", "nickname", new Date());
u.setId(1); // Added with EDIT 1
// testGson();
testJackson();
}
private static void testJackson()
{
Thread t = new Thread("Test", u, new Date(), new Date());
t.setId(1); // Added with EDIT 1
u.getThreads().add(t);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
try
{
mapper.writeValue(new File("result.json"), u);
}
catch {/[various exceptions catched, but a JsonMappingException was thrown]}
}
private static void testGson()
{
Gson gson = new Gson();
System.out.println(u.toString());
System.out.println(gson.toJson(u, User.class));
Thread t = new Thread("Test", u, new Date(), new Date());
u.getThreads().add(t);
//This raise an exception overflow
System.out.println(gson.toJson(u, User.class));
}
}
To solve the problem, on jackson side, I tried to use this annotation
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
on both User and Thread class. However, it doesn't solve the problem.
On gson side, I read about the GraphAdapterBuilder class, but I wasn't able to properly use it. I don't find any jar, so I copy/pasted the source code from here. However, there is a compile time error at this line
private final ConstructorConstructor constructorConstructor = new ConstructorConstructor();
because the ConstructorConstructor() is undefined; the right syntax should be
ConstructorConstructor(Map<Type>, InstanceCreator<?> instanceCreators)
So, is there a definitive solution to this problem? Obviously, I can't use transient variables.
EDIT 1
I finally found the issue with jackson. In the test class, I forgot to initialize the id field (in real scenarios it is initialized by the database) and this is the reason of the exception. When I finally set the id, all works. This is the output
{
"id" : 1,
"email" : "mail",
"password" : "password",
"nick" : "nickname",
"registeredDate" : 1414703168409,
"threads" : [ {
"id" : 1,
"thread" : null,
"user" : 1,
"title" : "Test",
"lastModifiedDate" : 1414703168410,
"createdDate" : 1414703168410,
"messages" : [ ],
"threads" : [ ]
} ],
"messages" : [ ]
}
When dealing with circular dependencies you need to build a parent-children JSON hierarchy, because the marshalling must be cascaded from root to the inner-most child.
For bi-directional associations, when the Parent has a one-to-many children collection and the child has a many-to-one reference to Parent, you need to annotate the many-to-one side with #JsonIgnore:
#Entity
#Table(name = "thread")
public class Thread extends RecognizedServerEntities implements java.io.Serializable
{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#org.codehaus.jackson.annotate.JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "author", nullable = true)
private User user;
//...other attributes, getters and setters
}
This way you will no longer have a Json serializing-time circular dependency.
Jackson
As said, I was able to solve the problem using
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=MyEntity.class)`
for each entity as suggested here.
The scope attribute was necessary to make sure that the name "id" is unique within the scope. Actually, without the scope attribute, as you can see here, it throws an exception saying
com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey#3372bb3f] (through reference chain: ParentEntity["children"]->java.util.ArrayList[0]->ChildEntity["id"])
...stacktrace...
Caused by: java.lang.IllegalStateException: Already had POJO for id (java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey#3372bb3f]
...stacktrace...
Gson
I still haven't found a clean way to serialize circular dependencies.
I have done this using org.codehaus.jackson.annotate.JsonManagedReference and org.codehaus.jackson.annotate.JsonBackReference in this way...
look at how i used #JsonManagedReference
#Id
#TableGenerator(name="CatId", table="catTable",pkColumnName="catKey",pkColumnValue="catValue", allocationSize=1)
#GeneratedValue(strategy=GenerationType.TABLE, generator="CatId")
#Column(name = "CategId", unique = true, nullable = false)
private long categoryId;
private String productCategory;
#JsonManagedReference("product-category")
#OneToMany(targetEntity=ProductDatabase.class,mappedBy="category", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<ProductDatabase> catProducts;
and then at the other end i used #JsonBackReference as shown below.
#Id#GeneratedValue
private int productId;
private String description;
private int productPrice;
private String productName;
private String ProductImageURL;
#JsonBackReference("product-category")
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "CategId")
private Category category;
just apply these annotations and check if it works for you.
Its not good design to serialize Hibernate POJO to client. As you may send some data to client location, which he is not authorize to view. You should create client POJO and copy data from hibernate POJO to client POJO, which you want to send to client. If you don't want to do that, you can use #JsonIgnore or Fetch all data eagerly.

Not-null property references a transient value - transient instance must be saved before current operation

I have 2 domain models and one Spring REST Controller like below:
#Entity
public class Customer{
#Id
private Long id;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
#Entity
public class Country{
#Id
#Column(name="COUNTRY_ID")
private Integer id;
// other stuff with getters/setters
}
Spring REST Controller:
#Controller
#RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Create new customer
*/
#RequestMapping( method=RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
#ResponseBody
public com.salesmanager.web.entity.customer.Customer createCustomer(#Valid #RequestBody Customer customer, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {
customerService.saveOrUpdate(customer);
return customer;
}
// other stuff
}
I am trying to call above REST service with below JSON as body:
{
"firstname": "Tapas",
"lastname": "Jena",
"city": "Hyderabad",
"country": "1"
}
Where country code 1 is already there in Country table. The problem is when I am calling this service getting below error:
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country
Any help will be appreciated!
Try putting CascadeType.ALL
#OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
#JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
I had a similar problem. Two entities: Document and Status.
Document had a relationship OneToMany with Status, that represented the history of Status the Document had.
So, there was a #NotNull #ManyToOne reference of Document inside Status.
Also, I needed to know the actual Status of Document. So, I needed another relationship, this time #OneToOne, also #NotNull, inside Document.
The problem was: how can I persist both entities the first time if both had a #NotNull reference to the other?
The solution was: remove #NotNull reference from actualStatus reference. This way, it was able to persist both entities.
Just to add an additional scenario that led me to this exact same error:
Make sure that any backward references that may exist are not null.
Specifically in my case, I was using Mapstruct to update some fields of the entity, e.g.
MyClass newInstance = //...
MyClass dbInstance = repository.findByField(someField);
MyClassMapper.MAPPER.update(dbInstance, newInstance);
repository.save(dbInstance);
And my poor implementation of MyClassMapper led the backward references of dbInstance fields to be set to null when they should be pointing back to dbInstance.
I got same error and this is how I solved it:
1st Entity:
#Entity
public class Person implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int personId;
private String name;
private String email;
private long phoneNumber;
private String password;
private String userType;
#OneToOne(fetch = FetchType.LAZY, mappedBy = "personCustomer", cascade
= CascadeType.ALL)
private Customer customer;
2nd Entity:
#Entity
public class Customer implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
#OneToOne(fetch = FetchType.LAZY, optional = false, cascade =
CascadeType.ALL)
#JoinColumn(name = "person_customer")
#JsonIgnore
private Person personCustomer;
My Controller:
#PostMapping("/customer/registration")
public PersonCustomer addCustomer(#RequestBody Person person)
{
Customer customer = new Customer(person);
person.setCustomer(customer);
Customer cust = customerRepo.save(customer);
logger.info("{}", cust);
Optional<Person> person_Cust =
personRepo.findById(cust.getPersonCustomer().getPersonId());
Person personNew = person_Cust.get();
PersonCustomer personCust = new PersonCustomer();
if(cust.equals(null))
{
personCust.setStatus("FAIL");
personCust.setMessage("Registration failed");
personCust.setTimestamp(personCust.timeStamp());
}
personCust.setStatus("OK");
personCust.setMessage("Registration OK");
personCust.setTimestamp(personCust.timeStamp());
personCust.setPerson(personNew);
return personCust;
}
The problem got solved when I added "person.setCustomer(customer);".
As both POJO classes has each others reference, so we have to "set" each others reference before using the JPA repository method(customerRepo.save(customer));
I had the exact same problem. The solution seems to be to send the JSON like this:
{
"firstname": "Tapas",
"lastname": "Jena",
"city": "Hyderabad",
"country": {"id":"1"}
}
I guess #RequestBody tries to map an entity not a single field since the Customer instance is referencing a Country instance.
(I have similarly two entities, joined. In the DB, records for the referenced entity (Country in your case) were already created but the entity creation (Customer in your case) with a json, provided the same error message. For me CascadeType.ALL not helped but the above written change in the JSON solved the problem. For further config of course CascadeType can be considered.)
you should change :
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
to :
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="COUNTRY_ID")
private Country country;
just delete nullable setting.

Categories

Resources