Spring Data & mongodb Converter error: java.lang.StackOverflowError - java

I am using Spring data connect to mongodb. Please see my problems below:
Now, I have two data models (User and Draft):
#Document
public class User implements Serializable {
#Id
private String id;
private String showName;
private String password;
//..... (other attributes)
#DBRef
private List<Draft> createdDraft = new ArrayList<Draft>();
//constructors
public User() {
super();
}
public User(String id, String showName, String password, //....other attributes
List<Draft> createdDraft) {
super();
this.id = id;
this.showName = showName;
this.password = password;
//....
}
//getters and setters
}
and
#Document
public class Draft {
#Id
private String id;
private String title;
private Date createTime;
private Date lastEditTime;
#DBRef
private User lastEditor;
#DBRef
private User mainAuthor;
#DBRef
private List<User> coAuthors = new ArrayList<User>();
private String externalURL;
//constructors..
public Draft() {
super();
}
public Draft(String id, String title, Date createTime, Date lastEditTime,
User lastEditor, User mainAuthor, String externalURL) {
super();
this.id = id;
this.title = title;
this.createTime = createTime;
this.lastEditTime = lastEditTime;
this.lastEditor = lastEditor;
this.mainAuthor = mainAuthor;
this.externalURL = externalURL;
}
//getters and setters...
}
In my project, I have created the user successfully
then, I would like to add a draft to the existing user.
public String CreateNewDraft(User mainAuthor)
{
Draft draft = new Draft();
draft.setMainAuthor(mainAuthor);
Date now = new Date(System.currentTimeMillis());
draft.setCreateTime(now);
mainAuthor.getCreatedDraft().add(draft);
//insert the draft --> Successful (1)
mongoOps.insert(draft);
//update the user --> Successful (2)
mongoOps.save(mainAuthor);
//find the last inserted draft. --> Errors.
Draft d = mongoOps.findOne(query(where("createTime").is(now) ), Draft.class);
return d.getId()
}
In (1), I have found a new "draft" document created in mongoDB, which has _id = it has 52a1591597d738f7b397be96.
In (2), I have found the existing user (mainAuhtor) document has one entry added in the createdDraft field like
[ { "$ref" : "draft" , "$id" : { "$oid" : "52a1591597d738f7b397be96"}}]
Exception & log:
processing failed; nested exception is java.lang.StackOverflowError
org.springframework.web.servlet.DispatcherServlet.
doDispatch(DispatcherServlet.java:972)
org.springframework.web.servlet.DispatcherServlet.
doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.p
rocessRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.d
oGet(FrameworkServlet.java:778)
javax.servlet.http.HttpServlet.service(HttpServlet .java:621)
javax.servlet.http.HttpServlet.service(HttpServlet .java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilt
er(WsFilter.java:51)
root cause
java.lang.StackOverflowError
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(Unknown Source)
java.net.SocketInputStream.read(Unknown Source)
java.io.BufferedInputStream.fill(Unknown Source)
java.io.BufferedInputStream.read1(Unknown Source)
java.io.BufferedInputStream.read(Unknown Source)
org.bson.io.Bits.readFully(Bits.java:46)
org.bson.io.Bits.readFully(Bits.java:33)
org.bson.io.Bits.readFully(Bits.java:28)
com.mongodb.Response.<init>(Response.java:40)
com.mongodb.DBPort.go(DBPort.java:124)
com.mongodb.DBPort.call(DBPort.java:74)
com.mongodb.DBTCPConnector.innerCall(DBTCPConnecto r.java:286)
com.mongodb.DBTCPConnector.call(DBTCPConnector.jav a:257)
com.mongodb.DBApiLayer$MyCollection.__find(DBApiLa yer.java:310)
com.mongodb.DBApiLayer$MyCollection.__find(DBApiLa yer.java:295)
com.mongodb.DBCollection.findOne(DBCollection.java :346)
com.mongodb.DBCollection.findOne(DBCollection.java :331)
com.mongodb.DBRefBase.fetch(DBRefBase.java:53)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.readValue(MappingMongoConverter. java:1046)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.access$100(MappingMongoConverter .java:77)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter$MongoDbPropertyValueProvider.get
PropertyValue(MappingMongoConverter.java:999)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.getValueInternal(MappingMongoCon verter.java:755)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter$2.doWithAssociation(MappingMongo Converter.java:265)
org.springframework.data.mapping.model.BasicPersis
tentEntity.doWithAssociations(BasicPersistentEntit y.java:269)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.read(MappingMongoConverter.java: 262)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.read(MappingMongoConverter.java: 223)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.readCollectionOrArray(MappingMon
goConverter.java:788)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.readValue(MappingMongoConverter. java:1048)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter.access$100(MappingMongoConverter .java:77)
org.springframework.data.mongodb.core.convert.Mapp
ingMongoConverter$MongoDbPropertyValueProvider.get
PropertyValue(MappingMon```
Can someone help me to take a look? Thanks so much!

This is a bug (or expected behaviour?) of spring data mongodb (I get this in 1.3.x version, haven't tried 1.4.x).
The problem is that User has reference to Draft and Draft to the same user instance so the converter gets into infinite loop.
#Document
public class User implements Serializable {
...
#DBRef
private List<Draft> createdDraft = new ArrayList<Draft>();
and
#Document
public class Draft {
...
#DBRef
private User lastEditor;
#DBRef
private User mainAuthor;
#DBRef
private List<User> coAuthors = new ArrayList<User>();
You should probably use simple id references, not DBRef (it is even suggested here http://docs.mongodb.org/manual/reference/database-references/ as suitable for most use cases)
If you find yourself using DBRef a lot you should consider using different kind of database, e.g. a graph database.

you should map your received entity (document) from the mongo database..
use the Springs Converter interface
for example:
public class ProfileReadConverter implements Converter<DBObject, Profile> {
#Override
public Profile convert(DBObject source) {
#SuppressWarnings("unchecked")
Profile p = new Profile((ObjectId) source.get("_id"), (boolean) source.get("active"), (String) source.get("name"),
(String) source.get("shortName"), (List<Person>) source.get("person"));
return p;
}
}
Profile.java
#Document(collection = "profile")
public class Profile {
#Id
private ObjectId id;
private boolean active;
#Indexed(unique = true)
#Field("ProfileName")
private String name;
private String shortName;
#DBRef
private List<Person> person = new ArrayList<Person>();
public Profile() {
}
#PersistenceConstructor
public Profile(ObjectId id, boolean active, String name, String shortName, List<Person> person,) {
this.id = id;
this.active = active;
this.name = name;
this.shortName = shortName;
this.person = person;
}
//getter and setter
Person.java
#Document(collection = "person")
public class Person extends Ressource {
#Indexed
private String firstname;
private String lastname;
#Field("email")
#Indexed(unique = true)
private String eMailAddress;
private String login;
#DBRef
private List<Profile> profiles = new ArrayList<Profile>();
public Person(ObjectId id, String firstname, String lastname, String eMailAddress, String login) {
this.setId(id);
this.firstname = firstname;
this.lastname = lastname;
this.eMailAddress = eMailAddress;
this.login = login;
}
#PersistenceConstructor
public Person(ObjectId id, String firstname, String lastname, String eMailAddress, String login,
List<Profile> profiles) {
this.firstname = firstname;
this.lastname = lastname;
this.eMailAddress = eMailAddress;
this.login = login;
this.profiles = profiles;
}
main or test class
...
Profile profileFind = mongoOps.findOne(new Query(where("shortName").is("SE")), Profile.class, "profile");

Related

rest api return duplicate values in postman and spring boot h2

I am new spring boot developer and i am trying to develope and rest api . when I do it ,I get and issues that my api return two duplicated response in postman .But i haven't code anythiong to get duplicated valuese in my code . the one of duplicate values is my model clase variable and athor one is table's attribute name .
below response in postman
model class
public class person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY )
private Long id;
#Column(name = "name")
private String Name ;
#Column(name ="surname")
private String Surname;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getSurname() {
return Surname;
}
public void setSurname(String surname) {
Surname = surname;
}
}
repository
#Repository
public interface personRepository extends JpaRepository<person,Long> {
}
controller
#RestController
#RequestMapping("/person")
public class personController {
#Autowired
private personRepository repository;
public personController(personRepository repository) {
this.repository = repository;
}
#GetMapping("/view/list/person")
private List<person> viewperson() {
return repository.findAll();
}
#PostMapping("/insert/person")
private person savePerson(#RequestBody person obj) {
return repository.save(obj);
}
#DeleteMapping("/delete/{id}")
private void delete(#PathVariable Long id) {
repository.deleteById(id);
}
}
application.properties
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialec
t
The problem is that you're not following the proper conventions in your naming strategy.
Due to this, Jackson doesn't know that your getters (getSurname(), getName()) are referencing the fields Surname and Name. That's why it serializes both your fields and your getters separately to JSON.
To fix this, you can follow the Java naming conventions and use a lowercase letter for the first character of your fields.
For example:
#Column(name = "name")
private String name; // Change this
#Column(name ="surname")
private String surname; // Change this
This will change your JSON output to:
{
"id": 1,
"name": "bryan",
"surname": "Nicky"
}
If you want to keep your JSON with capital letters, you can use the #JsonProperty annotation:
#JsonProperty("Name") // Add this
#Column(name = "name")
private String name;
#JsonProperty("Surname") // Add this
#Column(name ="surname")
private String surname;
Unrelated to your question, but according to those naming conventions, your classes should start with a capital (eg. Person, PersonController, PersonRepository, ...).

API throwing StackOverflow Error with a #OneToMany Relationship

I have made some changes to my MYSQL database so that a Product can have multiple Images associated with it (One to Many), however since making this change I am seeing some weird behaviour and the program throws a StackOverflow Exception. It seems as if the program is stuck in a continuous loop before crashing and throwing the error.
My model classes are structured as follows:
#Entity
#Table(name="products")
public class Products {
public Products(String name, String price, String added_on, String category_id, String image_name, String description, List<ImageModel> imageModel) {
super();
this.name = name;
this.price = price;
this.added_on = added_on;
this.category_id = category_id;
this.image_name = image_name;
this.description = description;
this.imageModel = imageModel;
}
public Products(String name, String price, String added_on, String category_id, String description) {
super();
this.name = name;
this.price = price;
this.added_on = added_on;
this.category_id = category_id;
this.description = description;
}
public Products() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
private String price;
private String added_on;
private String category_id;
private String image_name;
private String description;
private String image_id;
#ManyToOne(optional=false)
#JoinColumn(name = "category_id", insertable=false, updatable=false)
private Category category;
#OneToMany(mappedBy = "product")
private List<ImageModel> imageModel;
// Getters & Setters
This class is then linked to ModelImage as follows:
#Entity
#Table(name = "image_table")
public class ImageModel {
public ImageModel() {
super();
}
public ImageModel(String name, String type, byte[] picByte, Products product) {
this.name = name;
this.type = type;
this.picByte = picByte;
this.product = product;
}
public ImageModel(String name, String type, byte[] picByte) {
this.name = name;
this.type = type;
this.picByte = picByte;
}
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "type")
private String type;
// image bytes can have large lengths so we specify a value
// which is more than the default length for picByte column
#Column(name = "picByte", length = 10000)
private byte[] picByte;
#ManyToOne
#JoinColumn(name="product_id")
private Products product;
// Getters Setters
When I add a product, the following code executes and seems to add everything as expected:
#PostMapping(value = "imageUploadMultiple")
public ResponseEntity<ImageResponse> addProductAndImages(#RequestParam("imageFiles") MultipartFile[] files, #RequestParam("productName") String productName, #RequestParam("productDescription") String productDescription, #RequestParam("productPrice") String productPrice, #RequestParam("categoryId") String categoryId) throws IOException {
// Need to save product first then get the id and save all images with the productId
Products products = productService.addProduct(productName, productDescription, productPrice, categoryId);
Arrays.asList(files).stream().forEach(file -> {
ImageModel img = null;
try {
img = new ImageModel(file.getOriginalFilename(), file.getContentType(), compressBytes(file.getBytes()), products);
imageRepository.save(img);
} catch (IOException e) {
e.printStackTrace();
}
});
return ResponseEntity.ok().build();
}
This endpoint accepts multiple images and form data which corresponds to the image(Product Details etc)
However, the problem occurs when I call the endpoint to get all products based on a particular categoryId:
#RequestMapping(value = "getProductsByCategory", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Products> getProductsByCategory(#RequestBody HashMap<String, String> request) {
String category_id = request.get("cat_id");
List<Products> list = productService.getProductsByCategory(category_id);
return list;
}
This then calls into the service class which then calls the repository code:
#Query("Select pro FROM Products pro WHERE pro.category_id=:cat_id")
List<Products> getByCategoryId(#Param("cat_id")String cat_id);
When I run the app in debug mode, I get the following data (At this time there is only one product for that particular categoryID):
Notice how 'ImageModel' is of a PersistentBag type. When i dig deeper into this I get the mapped images to the particular product. In this instance there is 4 product images for the product. When i dig even deeper I notice there is just a continuous loop:
The error is as follows
java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_251]
at java.lang.ClassLoader.defineClass(ClassLoader.java:756) ~[na:1.8.0_251]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_251]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468) ~[na:1.8.0_251]
at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[na:1.8.0_251]
at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[na:1.8.0_251]
Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.youtube.ecommerce.model.Products["imageModel"]->org.hibernate.collection.internal.PersistentBag[0]->com.youtube.ecommerce.model.ImageModel["product"]->com.youtube.ecommerce.model.Products["imageModel"]->org.hibernate.collection.internal.PersistentBag[0]->com.youtube.ecommerce.model.ImageModel["product"]->com.youtube.ecommerce.model.Products["imageModel"]->org.hibernate.collection.internal.PersistentBag[0]->com.youtube.ecommerce.model.ImageModel["product"]->com.youtube.ecommerce.model.Products["imageModel"]->org.hibernate.collection.internal.PersistentBag[0]->com.youtube.ecommerce.model.ImageModel["product"]->com.youtube.ecommerce.model.Products["imageModel"]->org.hibernate.collection.internal.PersistentBag[0]
The error just keeps going and going so i didnt post the full thing but it continuously says the same thing over and over again.
Im really struggling to understand whats gone wrong here!!
Its because when you will serialize your entity, you will have graph like
Product->Image[]->Product->Image[]->Product-> and so on
so you have to cut the recursion somewhere, eg using #JsonIgnore or use #JsonManagedReference, #JsonBackReference`
This is exactly depicted on one of your images that you peek into the entity.

Error reading entity from input stream Dropwizard example

I'm attempting to use this dropwizard example and build off of it. I tried to add a column userName to the people table in Person.java like below
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "fullName", nullable = false)
private String fullName;
#Column(name = "jobTitle", nullable = false)
private String jobTitle;
#Column(name = "userName", nullable = false)
private String userName;
public Person() {
}
public Person(String fullName, String jobTitle, String userName) {
this.fullName = fullName;
this.jobTitle = jobTitle;
this.userName = userName;
}
I added the appropriate getters and setters, and equals method.
However I'm getting an error reading entity from input stream in this block.
#Test
public void testPostPerson() throws Exception {
final Person person = new Person("Dr. IntegrationTest", "Chief Wizard", "Dr. Wizard");
final Person newPerson = RULE.client().target("http://localhost:" + RULE.getLocalPort() + "/people")
.request()
.post(Entity.entity(person, MediaType.APPLICATION_JSON_TYPE))
--> .readEntity(Person.class);
assertThat(newPerson.getId()).isNotNull();
assertThat(newPerson.getFullName()).isEqualTo(person.getFullName());
assertThat(newPerson.getJobTitle()).isEqualTo(person.getJobTitle());
assertThat(newPerson.getUserName()).isEqualTo(person.getUserName());
}
the input stream error is caused by the following
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "code" (class com.example.helloworld.core.Person), not marked as ignorable (4 known properties: "fullName", "id", "userName", "jobTitle"])
will #JsonIgnoreProperties annotation at the class level solve this problem? Is this safe practice?
EDIT: PersonResource.java
#Path("/people/{personId}")
#Produces(MediaType.APPLICATION_JSON)
public class PersonResource {
private final PersonDAO peopleDAO;
public PersonResource(PersonDAO peopleDAO) {
this.peopleDAO = peopleDAO;
}
#GET
#UnitOfWork
public Person getPerson(#PathParam("personId") LongParam personId) {
return findSafely(personId.get());
}
#GET
#Path("/view_freemarker")
#UnitOfWork
#Produces(MediaType.TEXT_HTML)
public PersonView getPersonViewFreemarker(#PathParam("personId") LongParam personId) {
return new PersonView(PersonView.Template.FREEMARKER, findSafely(personId.get()));
}
#GET
#Path("/view_mustache")
#UnitOfWork
#Produces(MediaType.TEXT_HTML)
public PersonView getPersonViewMustache(#PathParam("personId") LongParam personId) {
return new PersonView(PersonView.Template.MUSTACHE, findSafely(personId.get()));
}
private Person findSafely(long personId) {
return peopleDAO.findById(personId).orElseThrow(() -> new NotFoundException("No such user."));
}
I think it's because the resource fails and throws a web application exception and code is actually the http status code.
Try it like this:
Response response = RULE.client().target("http://localhost:" + RULE.getLocalPort() + "/people")
.request()
.post(Entity.entity(person, MediaType.APPLICATION_JSON_TYPE));
assertEquals(200, response.getStatus());
Person newPerson = response.readEntity(Person.class);
....
You may also debug like this:
String responseString = response.readEntity(String.class);
Which will dump you the body of the response.

How to correctly bind form to #ManyToOne structure and save to DB. Spring MVC, Hibernate

I'm a novice java developer and now develop User Management application using Spring-Hibernate. I have two entities User and Email. And User entity has a field Email which is mapped to Email entity as #ManyToOne. Any Email can be used by multiple users.
When I save a new User in DB for every new user I get a new row Email, even if the same record is already in the Email Table. How to properly make save operation to avoid duplication of the same records in the table Email?
User.java
#Entity
#Table(name = "USER")
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="ID")
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "email_id")
private Email email;
public User(){
}
public Email getEmail() {
return email;
}
public void setEmail(Email email) {
this.email = email;
}
...
}
Email.java
#Entity
#Table(name = "EMAIL")
public class Email implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="ID")
private Long id;
#Column(name = "emailaddress")
private String emailaddress;
#OneToMany (mappedBy = "email", targetEntity=User.class)
private Set<User> user= new HashSet<User>();
public Email() {
}
public Email(String emailaddress) {
this.emailaddress = emailaddress;
}
public String getEmailaddress() {
return emailaddress;
}
public void setEmailaddress(String emailaddress) {
this.emailaddress = emailaddress;
}
...
}
Controller.java
#Transactional
#RequestMapping(value = "/adduser", method = RequestMethod.POST)
public String saveOrder(#ModelAttribute("user") User user, BindingResult result, #RequestParam String action){
emailDAO.create(user.getEmail());
userDAO.create(user);
return "index";
...
}
EmailDAO.java
#Transactional
#Repository
public class EmailDAO{
#Autowired
private SessionFactory sessionFactory;
public Email create(Email email) {
sessionFactory.getCurrentSession().save(email);
return email;
}
}
UserDAO.java
#Transactional
#Repository
public class UserDAO{
#Autowired
private SessionFactory sessionFactory;
public User create(User user) {
sessionFactory.getCurrentSession().save(user);
return user;
}
}
webform.jsp
<form:form action="${formUrl}" method="post" modelAttribute="user">
<form:label path="name" for="appname">username</form:label>
<form:input path="name" id= "appname" cssClass="form-control"/>
<form:label path="email.emailaddress" for="appemail">Email</form:label>
<form:input path="email.emailaddress" id= "appemail"/>
<button type="submit" name="action" value="Add">Save</button>
</form:form>
database diagram
Example of the DB records
That is because you keep on saving the Email as a new Record
#Transactional
#RequestMapping(value = "/adduser", method = RequestMethod.POST)
public String saveOrder(#ModelAttribute("user") User user, BindingResult result, #RequestParam String action){
emailDAO.create(user.getEmail()); // Inserting Email as New Record
userDAO.create(user);
return "index";
...
}
And you don't have unique=true on Email Entity
#Column(name = "emailaddress", unique = true)
private String emailaddress;
Which you should ideally have so that there will be no duplicate Emails will get inserted even by accidentally.
You need to modify EmailDAO
#Transactional
#Repository
public class EmailDAO{
#Autowired
private SessionFactory sessionFactory;
public Email create(Email email) {
sessionFactory.getCurrentSession().save(email);
return email;
}
public Email getEmail(String inputEmail) {
Email email = null;
Query query = sessionFactory.getCurrentSession().createQuery("FROM Email e WHERE e.emailaddress = :email");
query.setString("email", inputEmail);
List emails = query.list();
if(emails != null && emails.size() > 0) {
email = (Email)emails.get(0);
} else {
email = new Email();
email.setEmailAddress(inputEmail);
}
return email;
}
}
And you getEmail
#Transactional
#RequestMapping(value = "/adduser", method = RequestMethod.POST)
public String saveOrder(#ModelAttribute("user") User user, BindingResult result, #RequestParam String action){
user.setEmail(emailDAO.getEmail(user.getEmail().getEmailAddress())); // Inserting Email as New Record
userDAO.create(user);
return "index";
...
}

Caused by: org.hibernate.MappingException: Could not determine type for

I have a JPA Entity as
#Entity
#Table(uniqueConstraints = #UniqueConstraint(columnNames = { "name", "market_version" }))
public class Market extends MutableEntity {
#Column(nullable = false)
private String name;
#Column
private String description;
#Column(name = "market_version", nullable = false)
private Version marketVersion;
public Market(final String name, final String description) {
this.name = name;
this.description = description;
this.marketVersion = new Version("1.0", VersionType.MAJOR, VersionStatus.ACTIVE);
} ... snipped
Which contains a Version and Version class looks like
public class Version {
private String name;
private VersionType type;
private VersionStatus status;
private DateTime publishedOn;
private DateTime retiredOn;
private Version parentVersion;
public Version(#Nonnull final String name, #Nonnull final VersionType type, #Nonnull final VersionStatus status) {
this.name = name;
this.type = type;
this.status = status;
}
}
enum VersionType {
MAJOR,
MINOR,
BOTH
}
enum VersionStatus {
ACTIVE,
RETIRED
}
When I try to save the market entity in test,
#Test
public void testMarket() {
final Market market = new Market("test", "test market");
final MarketCrudService crudService = new MarketCrudService(jpaRule.getEntityManager());
crudService.create(market);
}
I see error
Caused by: org.hibernate.MappingException: Could not determine type for: com.myorg.project.versioning.entities.Version, at table: Market, for columns: [org.hibernate.mapping.Column(market_version)]
What exactly is the issue here? How can I fix it?
You either have to make Version a full entity with it's own table like you did with Market or if you want to save it as a part of Market you should make it embeddable using the #Embeddable annotation.
If you make it embeddable then you will have to remove the #Column annotation from the marketVersion field in Market.

Categories

Resources