API throwing StackOverflow Error with a #OneToMany Relationship - java

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.

Related

How to fix "Entities and Pojos must have a usable public constructor" error?

I'm trying to setup Room in my Android application. I'm getting this error but I really don't understand why.
Full error : Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
I'm using version 1.1.1 of Room. I tried empty constructors, constructors with params and also fixed all the warnings that I had so that nothing else could be the problem.
Here are my entities :
Marker Entity
#Entity(tableName = "markers")
public class Marker {
public Marker(#Nullable String title, #Nullable String snippet, String latitude, String longitude, float color) {
this.title = title;
this.snippet = snippet;
this.latitude = latitude;
this.longitude = longitude;
this.color = color;
}
#PrimaryKey(autoGenerate = true)
private int id;
private String title;
private String snippet;
private String latitude;
private String longitude;
private float color;
/* Getters and setters */
}
Photo Entity
#Entity(tableName = "photos",
foreignKeys = #ForeignKey(entity = Marker.class,
parentColumns = "id",
childColumns = "marker_id"),
indices = {#Index("marker_id")})
public class Photo {
public Photo(String imageBase64, int markerId) {
this.imageBase64 = imageBase64;
this.markerId = markerId;
}
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = "image")
private String imageBase64;
#ColumnInfo(name = "marker_id")
private int markerId;
/* Getters and setters */
}
Network Entity
#Entity(tableName = "networks",
foreignKeys = #ForeignKey(entity = Marker.class,
parentColumns = "id",
childColumns = "marker_id"),
indices = {#Index("marker_id")})
public class Network {
public Network(String ssid, String bssid, String capabilities, long timestamp, int markerId) {
this.ssid = ssid;
this.bssid = bssid;
this.capabilities = capabilities;
this.timestamp = timestamp;
this.markerId = markerId;
}
#PrimaryKey(autoGenerate = true)
private int id;
private String ssid;
private String bssid;
private String capabilities;
private long timestamp;
#ColumnInfo(name = "marker_id")
private int markerId;
/* Getters and setters */
}
And here is my dependencies for Room in my build.gradle file :
def room_version = "1.1.1"
implementation "android.arch.persistence.room:runtime:$room_version"
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
I looked at many questions like this and none of them solved my problem.
The error was due to a mistake in the MarkerDao class and not the Entity itself (somehow).
More precisely, a function was trying to get a LatLng object from a SELECT string, string from ... query:
#Query("SELECT latitude, longitude FROM markers WHERE id = :id")
LatLng getMarkerLatitude(int id);
This error was very annoying to debug as it gives no details. If someone finds this, comment out your entities and DAOs and uncomment them one at a time to see where the error starts happening.
Good luck!
Source: I work with #Jean-Christophe Martel
Create empty constructors like this.
public Marker(){};
public Photo(){};
public Network(){};
or you could remove all the constructors. Clean the project and rebuild. Check if this works.

Extending/modifying generated entities in Hibernate

I am creating a REST api service for a mysql database. I've generated classes using IntelliJ's persistence tool. It does a pretty good job.
There are some quirks to the schema that I am working with. The users want the endpoints to be accessible by another property other than the "id" primary key column.
Ex: /object/<name property>' versus/object/`.
Here is the catch though. The schema can change. The name property is not going anywhere though so I can safely assume that will always be on the object.
I've learned that you can use Superclasses to force these generated entites to have custom properties without affecting the database schema. I dont want to make a model change in the generated entity and have that update the database table layout as it is not my database.
I have a class called Animal.
#Entity
#Table(name = "animals", schema = "xyz123", catalog = "")
public class AnimalEntity extends AnimalSuperclass {
private Integer id;
private String name;
private String description;
#Id
#Column(name = "id", nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Basic
#Column(name = "name", nullable = true, length = 80)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "description", nullable = true, length = 255)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RoleEntity that = (RoleEntity) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(description, that.description);
}
#Override
public int hashCode() {
return Objects.hash(id, name, description);
}
}
I have to manually add extends AnimalSuperclass. Which is fine for now. Eventually I am going to try to generate these using .xmls on runtime.
Then I have this superclass..
#MappedSuperclass
public class AnimalSuperclass implements Serializable {
private String testMessage;
private String name;
private Integer id;
#Transient
public String getTestMessage() {
return this.testMessage;
}
public void setTestMessage(String id) {
this.testMessage = testMessage;
}
}
What I want to do is force the #Id annotation to be on the name property from within the superclass. Something like this..
#MappedSuperclass
public class AnimalSuperclass implements Serializable {
private String testMessage;
private String name;
private Integer id;
#Transient
public String getTestMessage() {
return this.testMessage;
}
public void setTestMessage(String id) {
this.testMessage = testMessage;
}
#Basic
#Id
#Column(name = "name", nullable = false, length = 15)
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
#NaturalId
#Column(name = "id", nullable = false)
private Integer getId() {
return id;
}
private void setId(Integer id) {
this.id = id;
}
}
How do I go about doing that? Currently this throws an error when I hit the endpoint: {"cause":null,"message":"Id must be assignable to Serializable!: null"}
Java is not my first language so I am not an expert by any means. But from what I've read, its not possible to override subclass properties from the superclass. Is there a better way to approach this, maybe by using RepositoryRestConfiguration? I am using PagingAndSortingRepository to serve these entities. I cannot extend the entities and use my superclass as a child as that creates a dType property in the schema and I cannot alter the table layout.
There is no hard link between the request and your entity. In your repository you can write methods that can query the data that is brought it from the request.
For example if they are requesting a name you can do something like
Page<AnimalEntity> findByName(String name, Pageable pageable);
in your Repository. Spring will take care of the rest and then you can call this in your controller.
#Service
public class AnimalService {
#Autowired
private AnimalEntityRepository animalRepo;
public Page<AnimalEntity> findAnimal(String name) {
Page<AnimalEntity> animals = animalRepo.findByName(name, new PageRequest(1,20));
return animals;
}
}
One thing to mention is that depending on how you configured Hibernate when sending an entity back to the client and the entity is seralized you might get an failed to lazy initialize error. If that is the case your entities will have to be converted to a POJO (plain old java object) and that sent back.

Caused by: org.hibernate.QueryException: could not resolve property from inner enum class

Having this domain class and using hibernate 3.2.6 integrated with JPA under spring 3.2.4
#Entity
public class PriorityDeviceKeyword {
public enum PriorityDeviceKey {
ALL ("ALL", "ALL DEVICES"),
IOS ("IOS", "IOS"),
ANDROID ("ANDROID","ANDROID");
private final String name;
private final String id;
private PriorityDeviceKey(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
}
#Id
private Long id;
#Column(name = "key")
private PriorityDeviceKey key;
#ManyToMany
#JoinTable(name = "t_priority_device_set", joinColumns = #JoinColumn(name = "priority_device__id", referencedColumnName = "id"))
private List<PriorityDevice> priorityDevices;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public PriorityDeviceKey getKey() {
return key;
}
public void setKey(PriorityDeviceKey key) {
this.key = key;
}
public List<PriorityDevice> getPriorityDevices() {
return priorityDevices;
}
public void setPriorityDevices(List<PriorityDevice> priorityDevices) {
this.priorityDevices = priorityDevices;
}
}
When executing this query that I have below method in my DAO class that I execute
#Override
#SuppressWarnings("unchecked")
public Set<PriorityDevices> findPriorityAreas(PriorityDevicesKey key) {
String jpql = "from PriorityDevices as pak where pak.key.name = :keyName";
Query query = entityManager.createQuery(jpql);
query.setParameter("keyName", key.getName());
List<PriorityDevices> priorityDevices = query.getResultList();
return new HashSet<PriorityDevices>(priorityDevices);
}
I get this Exception thrown by the application:
2015-01-14 13:14:50,936 ERROR [com.controller.errors.Error500Controller] - Application thrown an exception
java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: name of: com.domain.PriorityDevicesKeyword [from com.domain.PriorityDevicesKeyword as
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:624)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:96)
at sun.reflect.GeneratedMethodAccessor440.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
Think these changes may work for you:
#Column(name = "key")
#Enumerated(EnumType.STRING)
private PriorityAreaKey key;
and
String jpql = "from PriorityAreaKeyword as pak where pak.key = :keyName";
Query query = entityManager.createQuery(jpql);
query.setParameter("keyName", key);
Hibernate stores enums as an oridnal. Or, when the field is annotated with #Enumerated(EnumType.STRING), as a string with the short name of the Enum. When annotated valid names would be {ALL, IOS, ANDROID}. Either way there is only a single field, the properties of the enum itself are not stored, they are constant after all.
If you want to query for an enum value you have to to query for pak.key = :key and use key as the parameter. Hibernate will do the required translation to ordinal or string.

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

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");

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