JPA giving a unknown entity reference - spring

My project is using JPA2/hibernate to map properties to their respective tables. As I understand it, I must put the property mappedby in the owner table and put JoinColumn in the child table(many side). I am getting the error as seen here:
Caused by: org.hibernate.AnnotationException: mappedBy reference an
unknown target entity property:
ninja.familyhomestay.domain.HouseImage.homestay_info in
ninja.familyhomestay.domain.HomestayInfo.houseImages
Here is my HomestayInfo class:
#Entity
#Table(name = "homestay_info")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "homestay_info")
data class HomestayInfo(
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
var id: Long? = null,
...
#OneToMany(mappedBy = "homestay_info", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var houseImages: MutableSet<HouseImage> = HashSet(),
...
)
and my houseImage class:
#Entity
#Table(name = "house_image")
#Document(indexName = "house_image")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
class HouseImage(
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
var id: Long? = null,
...
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "homestay_info_id")
var homestayInfo: HomestayInfo? = null
) : Serializable
Any ideas? I am also using liquid to create the tables in the db.

In your HomestayInfo class, while mentioning #OneToMany relationship, you are mentioning value of mappedBy attribute as homestay_info, while in HouseImage class there is no field with the name homestay_info.
You should have same field name mentioned in mappedBy and the attribute specifying the bilateral relationship in the other class.
Either rename homestayInfo to homestay_Info in the below statement :
var homestayInfo: HomestayInfo? = null
or
rename the value in mappedBy field to homestayInfo

Related

ERROR: UPDATE or DELETE statement on table

In a project with Spring Boot and Spring JPA I Have two entities FunctionConfiguration and InvokeFunctionResult.
#Entity
#Table(name = "function_configuration")
public class FunctionConfigurationEntity {
#Id
#Column(name = "id_function_configuration")
#GeneratedValue(strategy = IDENTITY)
private Integer idFunctionConfiguration;
}
#Entity
#Table(name = "invoked_function_result")
public class InvokedFunctionResultEntity {
#Id
#Column(name = "id_invoked_result_function")
#GeneratedValue(strategy = IDENTITY)
private Integer idInvokedResultFunction;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "function_configuration_id", nullable = false, foreignKey = #ForeignKey(name = "function_configuration_fk"), referencedColumnName = "id_function_configuration")
private FunctionConfigurationEntity functionConfiguration;
}
The InvokeFunctionResult has foreign key the id of the FunctionConfiguration.
If I try to do a delete with an id of a functionConfiguration that is present in the InvokeFunctionResult:
#Transactional
#Modifying
#Query(value = "DELETE FROM FunctionConfigurationEntity fce WHERE fce.idFunctionConfiguration = idFunctionConfiguration")
void deleteByFunctionConfigurationId(#Param("idFunctionConfiguration") Integer functionConfigurationId);
I get the following error: Caused by: org.postgresql.util.PSQLException: ERROR: UPDATE or DELETE statement on table "function_configuration" violates foreign key constraint "function_configuration_fk" on table "invoked_function_result"
How can I fix it?

Spring JPA Self Reference Issue

I created a table, Category in Postgres which holds both parent and child categories and references to itself (it's a self join table)
The table comprises of following columns: id, parent_id, start_date, end_date, status
I also have one row for root parent whose id = 0. So, any first level categories have root as its parent.
Example: Apparel > Women. Here Apparel(id=1) is a first level category whose parent_id = 0. Women is another category whose parent_id = 1.
I am using Spring JpaRepository findAll on my table and this is leading to infinite recursion.
POJO
#Table(name = "ofr_category")
#Getter
#Setter
#NoArgsConstructor
public class Category {
#Id
#Column(name = "cat_id", updatable = true, unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CATEGORY_SEQ")
#SequenceGenerator(sequenceName = "CATEGORY_ID_SEQ", allocationSize = 1, name = "CATEGORY_SEQ")
private Long id;
#Column(name = "cat_name")
private String name;
#Column(name = "cat_status")
private String status;
#Column(name = "start_date")
private LocalDate startDate;
#Column(name = "end_date")
private LocalDate endDate;
#Column(name = "parent_id")
private Long parentId;
#JsonBackReference
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "parent_id", insertable = false, updatable = false)
private Category parentCategory;
#JsonManagedReference
#OneToMany(fetch = FetchType.EAGER, mappedBy = "parentCategory")
private List<Category> childCategories;
public Category getParentCategory(){
return parentCategory;
}
}
Exception seen
"Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct self-reference leading to cycle (through reference chain: java.util.ArrayList[0]->com.test.category.dataobject.Category[\"parentCategory\"]->com.test.category.dataobject.Category[\"parentCategory\"]->com.test.category.dataobject.Category[\"parentCategory\"])",
Maybe you can have a look into #JsonIdentityInfo, which solved a similar problem for me. You can check if this basic annotation works for you.:
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Category {
...
}

Cannot delete or update a parent row HIBERNATE one to many

I'm getting this error when I try to delete a pet. This pet, has visits (child) but I have defined CASCADE.ALL in pet entity. Any idea ?
ERROR:
Cannot delete or update a parent row: a foreign key constraint fails (web_customer_tracker.visits, CONSTRAINT visits_ibfk_1 FOREIGN KEY (pet_id) REFERENCES pets (pet_id))
#Entity
#Table(name = "pets")
public class Pet {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "pet_id")
private int pet_id;
.....
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "visit_id")
private Set<Visit> visits;
Visit class:
#Entity
#Table(name = "visits")
public class Visit {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "visit_id")
private int visit_id;
#ManyToOne
#JoinColumn(name = "pet_id")
private Pet pet;
....
you are using mappedBy in a wrong way
the mappedBy refers to the object name in the opposite side
like this
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pet")
private Set<Visit> visits;
or if you want to map it by the JoinColum try this
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "pet_id")
private Set<Visit> visits;

java-graphql - Unable to match type definition with java type

I am using graphql-spring-boot to serve graphql queries from my spring-boot project. Right now I am working on matching the graphql scheme type definitions with my spring entites. For whatever reason, I am getting the following error:
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Unable to match type definition (ListType{type=TypeName{name='HomestayInfo'}}) with java type (class ninja.familyhomestay.domain.HomestayInfo): Java class is not a List or generic type information was lost: class ninja.familyhomestay.domain.HomestayInfo
at com.coxautodev.graphql.tools.TypeClassMatcher.error(TypeClassMatcher.kt:19)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:79)
at com.coxautodev.graphql.tools.TypeClassMatcher.match(TypeClassMatcher.kt:25)
Here's my graphql schema defintion for HomestayInfo:
type HomestayInfo{
homestayName: String
homestayShortDescription: String
homestayDescription: String
address: Address
rooms: [Room]
houseImages: [HouseImage]
pets: [Pet]
}
and the corresponding kotlin entity:
#Entity
#Table(name = "homestay_info")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "homestay_info")
data class HomestayInfo(
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
var id: Long? = null,
#Column(name = "homestay_name")
var homestayName: String? = null,
#Column(name = "homestay_short_description")
var homestayShortDescription: String? = null,
#Column(name = "homestay_description")
var homestayDescription: String? = null,
#OneToOne
#JoinColumn(name = "address_id")
var address:Address?=null,
#OneToMany(mappedBy = "homestayInfo", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var rooms: MutableSet<Room> = HashSet(),
#OneToMany(mappedBy = "homestayInfo", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var houseImages: MutableSet<HouseImage> = HashSet(),
#OneToMany(mappedBy = "homestayInfo", cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
var pets: MutableSet<Pet> = HashSet()
) : Serializable
I don't see anything wrong with the mapping. Any ideas?
Adding scalar Date to the top of your schema.graphqls file should do the trick! So your file would look like such:
scalar Date
schema { // not sure if your file has this, but mine does
query: Query
}
type HomestayInfo{
...

Hibernate - map a row to either of two subclasses

I have a Superclass
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "entity_type", discriminatorType = DiscriminatorType.STRING)
#Table(name = "my_super")
public abstract class MySuper{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "super_id")
private Long id;
}
and two subclasses
#Entity
#DiscriminatorValue("sub1")
public class Sub1 extends MySuper {}
#Entity
#DiscriminatorValue("sub2")
public class Sub2 extends MySuper {}
Now if another class has both of these subclasses in it, is it possible to instantiate one of them through the same join table - same row ??
For instance:
#Entity
#Table(name = "caller")
public class Caller{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "caller_id")
Long id;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "caller_super", joinColumns = #JoinColumn(name = "caller_id"), inverseJoinColumns = #JoinColumn(name = "super_id"))
private Set<Sub1> sub1s;
#ManyToOne(fetch = FetchType.LAZY)
#JoinTable(name = "caller_super", joinColumns = #JoinColumn(name = "caller_id"), inverseJoinColumns = #JoinColumn(name = "super_id"))
Sub2 sub2;
}
I keep getting this error when trying to instantiate a Caller Object:
org.springframework.orm.hibernate3.HibernateSystemException: could not set a field value by reflection setter of my.test.Caller.sub2; nested exception is org.hibernate.PropertyAccessException: could not set a field value by reflection setter of my.test.Caller.sub2
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:679)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:102)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:368)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
nested exception is org.hibernate.PropertyAccessException: could not set a field value by reflection setter
i think this two line shouldnt be same
#JoinTable(name = "caller_super", joinColumns = #JoinColumn(name = "caller_id"), inverseJoinColumns = #JoinColumn(name = "super_id"))
private Set<Sub1> sub1s;
--
#JoinTable(name = "caller_super", joinColumns = #JoinColumn(name = "caller_id"), inverseJoinColumns = #JoinColumn(name = "super_id"))
private Sub2 sub2;
because they are not same entity and their join table should be different. For ManyToMany relationship type is Sub1 but if you try to put them same table hibernate will try to put Sub2 to sub1s . But it is not vaild. Try to change your join table. For ManyToOne relationship.

Resources