Spring Crud on Nested Property - spring

I have a spring crud repository:
#Repository
public interface CrudCVVacancyMatchRepository extends CrudRepository<CVVacancyMatchEntity, Long> {
The CVVacancyMatchEntity object has an Vacancy property. I'm trying to write a query method on properties of the Vacancy property.
The following query method works fine (Vacancy has a string property called name):
Iterable<CVVacancyMatchEntity> findByVacancyName(String name);
But Vacancy also has properties as a set:
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "vacancy_industries", joinColumns = { #JoinColumn(name = "fk_vacancy", referencedColumnName = "id") }, inverseJoinColumns = { #JoinColumn(name = "fk_industry", referencedColumnName = "id") })
private final Set<IndustryEntity> industries = Sets.newHashSet();
This doesn't work:
Iterable<CVVacancyMatchEntity> findByVacancyIndustries(Set<IndustryEntity> industryEntities);
I get ERROR SqlExceptionHelper:146 - Syntax error in SQL statement
select cvvacancym0_.id as id1_19_, cvvacancym0_.comment as comment2_19_, cvvacancym0_.cv_id as cv_id4_19_, cvvacancym0_.rating as rating3_19_, cvvacancym0_.user_id as user_id5_19_, cvvacancym0_.vacancy_id as vacancy_6_19_ from cv_vacancy_match cvvacancym0_ cross join vacancy vacancyent1_ cross join vacancy_industries industries2_, industry industryen3_ where cvvacancym0_.vacancy_id=vacancyent1_.id and vacancyent1_.id=industries2_.fk_vacancy and industries2_.fk_industry=industryen3_.id and .=? [42001-182]
Any idea?

Related

Encountered with JPA ManytoMany Relationship Build time errors with IntelliJ IDEA

I'm very new to this topic so i followed a tutorial. after following steps i got some build time errors.
I have imported javax persistence like this.
import javax.persistence.*;
Then the student model class
#Entity
#Table(name="STUDENT")
public class Student {
#Id
#GeneratedValue
private Integer studentId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinTable(name="Enrollment", joinColumns = {#JoinColumns(name="student_id")},
inverseJoinColumns = {#JoinColumns(name="course_id")})
private List<Course> courses = new ArrayList<>();
}
The Course model class.
#Entity
#Table(name="COURSE")
public class Course {
#GeneratedValue
private Integer id;
#ManyToMany(mappedBy ="courses")
private List<Student> students = new ArrayList<>();
These are set of errors that i have got
incompatible types: javax.persistence.JoinColumns cannot be converted to javax.persistence.JoinColumn
cannot find symbol
symbol: method name()
location: #interface javax.persistence.JoinColumns
annotation #javax.persistence.JoinColumns is missing a default value for the element 'value'
Can anyone help me to get rid of this issues?
Thanks.
A #JoinTable annotation really has a joinColumns parameter, but the syntax you had used is not correct. If tables are joined by only column and inverse column you shouldn't use a #JoinColumns annotation. You have to change it in the following way:
#Entity
#Table(name="STUDENT")
public class Student {
#Id
#GeneratedValue
private Integer studentId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinTable(
name="Enrollment",
joinColumns = #JoinColumn(name="student_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name="course_id", referencedColumnName = "id"))
private List<Course> courses = new ArrayList<>();
}
and only if joining goes by more then one column you have to do something like this:
#Entity
#Table(name="STUDENT")
public class Student {
#Id
#GeneratedValue
private Integer studentId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinTable(
name="Enrollment",
joinColumns = #JoinColumns{
#JoinColumn(name="student_id", referencedColumnName = "id"),
#JoinColumn(name="another_id", referencedColumnName = "another_id")
},
inverseJoinColumns = #JoinColumn(name="course_id", referencedColumnName = "id"))
private List<Course> courses = new ArrayList<>();
}
Hope it will help

How to create Predicate BooleanExpression for many to many relations in QueryDSL

How can inner join be done on Many to Many relations using Predicate BooleanExpression?
I have 2 entities
public class A {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToMany(fetch = FetchType.LAZY,
cascade = { CascadeType.DETACH, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.PERSIST})
#JoinTable(name = "a_b_maps",
joinColumns = #JoinColumn(name = "a_id", nullable =
false,referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "b_id", nullable = false,
referencedColumnName = "id")
)
private Set<B> listOfB = new HashSet<B>();
}
public class B {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToMany(fetch = FetchType.LAZY,
cascade = { CascadeType.DETACH, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.PERSIST})
#JoinTable(name = "a_b_maps",
joinColumns = #JoinColumn(name = "b_id", nullable =
false,referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "a_id", nullable = false,
referencedColumnName = "id")
)
private Set<A> listOfA = new HashSet<A>();
}
A Base repo
#NoRepositoryBean
public interface BaseRepository<E, I extends Serializable>
extends JpaRepository<E, I> {
}
And a repository class for A
public interface Arepo extends BaseRepository<A, Integer>,
QueryDslPredicateExecutor<A> {
Page<A> findAll(Predicate predicate, Pageable pageRequest);
}
Now I want to use A Repo with Predicate query. I need to form a predicate where I can load A based on some given Bs
I tried
QA a = QA.a;
QB b = QB.b;
BooleanExpression boolQuery = null;
JPQLQuery<A> query = new JPAQuery<A>();
query.from(a).innerJoin(a.listOfB, b)
.where(b.id.in(someList));
Now I am able to form a JPQLQuery, but the repository expects a Predicate. How can I get Predicate from the JPQLQuery??
Or, how can the inner join be achieved using Predicate?
I am able to create a Predicate with the help of answer given here
https://stackoverflow.com/a/23092294/1969412.
SO, instead of using JPQLQuery, I am directly using
a.listOfB.any()
.id.in(list);
This is working like a charm.

Spring MVC - loading data from database

I have two entities which are in many to many relation and I can't load Set <Category> categories. These fields are filled in the database.
#Entity
#Table(name="Product")
public class Product {
#Id
#GeneratedValue
private int idProduct;
private String status;
private String name;
#ManyToMany(fetch = FetchType.EAGER, mappedBy= "products")
private Set <Category> categories;
}
#Entity
#Table(name="Category")
public class Category {
#Id
#GeneratedValue
private int idCategory;
private String name;
#ManyToMany(fetch = FetchType.EAGER)
private Set <Product> products;
}
This returns nothing int the view and the loop doesn't rotate even once.
<c:forEach items="${product.categories}" var="items">
<p>${items.name}</p>
</c:forEach>
I join the schema. Could someone write what to do to make it work, please?
enter image description here
This not works.
#Entity
#Table(name="Category")
public class Category {
#Id
#GeneratedValue
private int idCategory;
private String name;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "Product_Category", joinColumns = {
#JoinColumn(name = "Category_idCategory", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "Product_idProduct",
nullable = false, updatable = false) })
private Set <Product> product;
Hibernate infers the sql that it needs to create from the annotation on the objects. Your product entity is telling hibernate to get information about the SQL join from the Category entity. This is from the mappedBy clause in the #ManyToMany annotation.
When it goes to the Category entity, it doesn't find what it needs, and it just gives an empty set.
Most #ManyToMany annotations are done with a join table. Here is a sample join table annotation
#JoinTable(name = "product_to_category", joinColumns = {
#JoinColumn(name = "category_id", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "product_id",
nullable = false, updatable = false) })
Depending on your schema, you might need to adjust the above annotation to get it working. It will give you a good start.

JPA Self Join using JoinTable

I have 1 entity call Item in which I want to be able to link parent items to children. to use a join table to create a parent/child relationship. I haven't been able to get any good documentation on. So if anyone has any thoughts I'm all ears.
Here is what I have... which works most of the time.
public class Item implements java.io.Serializable {
#Id
private Long id;
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinTable(name = "ITEMTOITEM", joinColumns = { #JoinColumn(name = "ITEMID") }, inverseJoinColumns = { #JoinColumn(name = "PARENTITEMID") } )
private Item parent;
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Item> children;
}
At times when I want to bring back objects that are tied to this item table I am getting an error of the following:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.webflow.engine.ActionExecutionException: Exception thrown executing [AnnotatedAction#6669ff5 targetAction = com.assisted.movein.web.common.nav.NavAction#6edf74b7, attributes = map['method' -> 'handleEntry']] in state 'oneTimeChargesAndFeesView' of flow 'in-flow' -- action execution attributes were 'map['method' -> 'handleEntry']'; nested exception is Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b04-fcs (04/11/2008))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: ORA-00904: "PARENTITEM_ITEMID": invalid identifier
Error Code: 904
Call: SELECT ITEMID, ITEMSHORTDESC, EFFENDDATE, ITEMDESC, PARENTITEM_ITEMID, ITEMTYPECODE FROM ITEM WHERE (ITEMID = ?)
bind => [1250]
Query: ReadObjectQuery(com.domain.Item)
Any help would be appreciated.
Try to use #JoinColumninstead:
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name = "PARENTITEMID", referencedColumnName = "ITEMID")
private Item parent;
#OneToMany(
cascade = {CascadeType.ALL},
orphanRemoval = true,
fetch = FetchType.LAZY
)
#JoinColumn(name = "PARENTITEMID")
private List<Item> children;
After a lot of reading on JPA 2.0 I figured out that I needed a newer version of Eclipselink 2.3+ in order to support what I was trying to do. Here is the code that actually worked in my case, but it will not work due to our dependency on an older version [EclipseLink 2.0.2]. Also another project's is still using Toplink-essentials JPA 1.0 which again does like this notation.
public class Item {
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinTable(name = "ITEMINCENTIVESMAPPING",
joinColumns = { #JoinColumn(name = "INCENTIVEITEMID", referencedColumnName = "ITEMID", insertable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "ITEMID", referencedColumnName = "ITEMID", insertable = false, updatable = false) } )
private Item parentItem;
#OneToMany(fetch = FetchType.LAZY)
#JoinTable(name = "ITEMINCENTIVESMAPPING",
joinColumns = { #JoinColumn(name = "INCENTIVEITEMID", referencedColumnName = "ITEMID") },
inverseJoinColumns = { #JoinColumn(name = "ITEMID", referencedColumnName = "ITEMID") } )
private List<Item> items;
}
I believe #JoinTable is only allowed on a #OneToOne or #OneToMany or #ManyToMany, I don't think it makes any sense on a #ManyToOne. Use a #JoinColumn, or a #OneToOne.
Also your #OneToMany does not make sense, the mappedBy must be an attribute and you have no parentItem, it should be parent, and parent should use a #JoinColumn.

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