How select records without parent with Hibernate using Criteria API?
Here is my Java code for select with parents
getSessionFactory().getCurrentSession().createCriteria(Category.class).add(
Restrictions.eq("parent", new Category(parentId))).list();
Category Java code
#Entity
#Table(name = "CATEGORY")
public class Category implements NamedModel{
#Id
#Column(name = "CATEGORY_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
#JoinTable(name = "CATEGORY_RELATIONS",
joinColumns = {
#JoinColumn(name = "CATEGORY_RELATIONS_CATEGORY_ID", referencedColumnName = "CATEGORY_ID")},
inverseJoinColumns = {
#JoinColumn(name = "CATEGORY_RELATIONS_PARENT_ID", referencedColumnName = "CATEGORY_ID")})
private Category parent;
#OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "parent")
private List<Category> children;//...
}
CategoryRelations Java code
#Entity
#Table(name = "CATEGORY_RELATIONS")
#IdClass(CategoryRelations.CategoryRelationsPrimaryKey.class)
public class CategoryRelations implements Serializable {
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private long categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private long parentId;
#Entity
#IdClass(CategoryRelationsPrimaryKey.class)
public static class CategoryRelationsPrimaryKey implements Serializable {
private long categoryId;
private long parentId;
}
}
You can use Restriction#isNull(propertyName) function for your requirements.
Restrictions.isNull("parent")
Related
I'm stuck at deal with this problem. I have 'Review Entity', and 'Heart Entitiy'. And I tried to show them homepage and detailpage separately!
Long countHeartByBookReviewId(Long bookReview_id);
i used jpa query method for showing how many heart it gets in details page..
and now i want to show review descending related to heart count in main page!
how can i make the code..?
#Entity
public class BookReview extends Timestamped {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
private Long id;
...
#Column
private String review;
#JoinColumn(name = "member_id", nullable = false)
#ManyToOne(fetch = FetchType.EAGER)
private Member member;
#OneToMany(mappedBy = "bookReview" , cascade = CascadeType.REMOVE)
private List<Comment> comment;
#JsonIgnore
#OneToMany(mappedBy = "bookReview", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Heart> heart;
and the other entitiy is here.
public class Heart {
#GeneratedValue(strategy = GenerationType.AUTO)
#Id
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "bookReview_id")
private BookReview bookReview;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "member_id")
private Member member;
and this is function for get menthod...
public ResponseDto<?> getHome() {
List<BookReview> book_review = book_reviewRepository.findAllByOrderByHeartDesc();
List<HomeResponseDto> book_reviewResponseDtoList = new ArrayList<>();
for (BookReview home : book_review) {
book_reviewResponseDtoList.add(HomeResponseDto.builder()
.id(home.getId())
.username(home.getMember().getUsername())
.thumbnail(home.getThumbnail())
.title(home.getTitle())
.author(home.getAuthor())
.publisher(home.getPublisher())
.review(home.getReview())
.heart(heartRepository.countHeartByBookReviewId(home.getId()))
.createdAt(home.getCreatedAt())
.modifiedAt(home.getModifiedAt())
.build()
);
}
return ResponseDto.success(book_reviewResponseDtoList);
}
please help me ......
i have three entites named depense ,benifice and categories , when i want to get the benefice_C and the Depenese_C in the category entity .this error displayed to me
“Illegal attempt to map a non collection as a #OneToMany, #ManyToMany or #CollectionOfElements” SpringBoot
Depens Entities
> #Entity
#Getter
#Setter
#Table(name="depense")
public class Depense {
#Id #GeneratedValue
#Column(name = "id_etab")
private Long idEtab;
#ManyToOne
#JoinColumn(name = "personnel_id")
private Personnel personnel;
#ManyToOne
#JoinColumn(name = "CATD")
private Categories categoriesD;
Benfice Entities
> public class Benifice {
#Column(name = "id_etab")
private Long idEtab;
#ManyToOne
#JoinColumn(name = "inscrit_id")
private Inscrit inscrit;
#ManyToOne
#JoinColumn(name = "be_C")
private Categories benificeC;
Categorie entite
> public class Categories implements Serializable {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idCat;
#OneToMany(mappedBy = "categoriesD", fetch = FetchType.LAZY)
private Depense depense;
#OneToMany(mappedBy = "benificeC", fetch = FetchType.LAZY)
private Benifice benifice;
Your #OneToMany mapping is not correct.
You would need a List/Set/Collection of Objects if you map OneToMany.
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idCat;
#OneToMany(mappedBy = "categoriesD", fetch = FetchType.LAZY)
private List<Depense> depense;
#OneToMany(mappedBy = "benificeC", fetch = FetchType.LAZY)
private List<Benifice> benifice;
I have an ClientUser entity with #OneToMany field customField:
#Entity
#Data
public class ClientUser {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "client_user_custom_field",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "field_id", referencedColumnName = "id"))
private Collection<ClientFieldValue> customFields;
}
And a ClientFieldValue entity:
#Entity
#Data
public class ClientFieldValue {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;
private String value;
}
How can I create ClientFieldValue's for all existing ClientUser?
I know that I can do smth like:
final Iterable<ClientUser> clientUsers = userRepository.findAll();
clientUsers.forEach(clientUser ->
clientUser.setCustomFields(Collections.singleton(new ClientFieldValue())));
userRepository.saveAll(clientUsers);
But I don't want to query all and save them after set.
Is there another way to do this?
I have a strange need in a project. Joining two n:m+attributes table (I will present the behavior with dummy attributes).
FirstTable (idPlace, idAddress,idSchool, wage) joined 1:m;
SecondTable (idPlace, idAddress,idSchool, qty, idEnterprise)
EDIT (example schema):
Of course that I have the tables Place, Address, School, Enterprise with theirs respective Ids, gets, sets and attributes implemented in the entity classes.
CODE:
Place
#Entity
#Table(name = "Place")
public class Place implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idLine")
private Long idLine;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.place")
private List<FirstTable> firstTables;
}
Address
#Entity
#Table(name = "Address")
public class Address implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idAddress")
private Long idAddress;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.address")
private List<FirstTable> firstTables;
}
School
#Entity
#Table(name = "School")
public class School implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idSchool")
private Long idSchool;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.school")
private List<FirstTable> firstTables;
}
FirstTable
#Entity
#Table(name = "FirstTable")
#AssociationOverrides({ #AssociationOverride(name = "pk.school", joinColumns = #JoinColumn(name = "idSchool")),
#AssociationOverride(name = "pk.address", joinColumns = #JoinColumn(name = "idAddress")),
#AssociationOverride(name = "pk.place", joinColumns = #JoinColumn(name = "idPlace")) })
public class FirstTable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EmbeddedId
protected FirstTablePK pk = new FirstTablePK();
}
FirstTablePK
#Embeddable
public class FirstTablePK implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#ManyToOne
private Address address;
#ManyToOne
private Place place;
#ManyToOne
private School school;
}
The above mentioned tables and joins are working perfectly. Now I want to join the FirstTable with the Second Table.
Enterprise
#Entity
#Table(name = "Enterprise")
public class Enterprise implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idEnterprise")
private Long idEnterprise;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pk.enterprise")
private List secondTables;
}
Now for the SecondTable I've followed the same logic to connect to the Enterprise. For connecting with the FirstTable I've tried this:
#Entity
#Table(name = "SecondTable")
#AssociationOverrides({
#AssociationOverride(name = "pk.firstTable", joinTable = #JoinTable(
name = "FirstTable", inverseJoinColumns = {
#JoinColumn(name = "idSchool", referencedColumnName = "idSchool"),
#JoinColumn(name = "idAddress", referencedColumnName = "idAddress"),
#JoinColumn(name = "idPlace", referencedColumnName = "idPlace") })),
#AssociationOverride(name = "pk.enterprise", joinColumns = #JoinColumn(name = "idEnterprise")) })
public class SecondTable implements Serializable{}
Something is not working in my annotation, I'm trying to do an inverseJoin to the FirstTable table. The compilation shows this error:
"org.hibernate.AnnotationException: A component cannot hold properties split into 2 different tables"
I've tried to provide a MV example.
Thanks in advance and I really need your help.
Hours later and many tries before I've managed to solve the problem. Actually the solution was much simpler that I was thinking initially.
Here it is:
#AssociationOverride(name = "pk.firstTable", joinColumns = {
#JoinColumn(name = "idSchool"),
#JoinColumn(name = "idAddress"),
#JoinColumn(name = "idPlace") }),
#AssociationOverride(name = "pk.enterprise", joinColumns = #JoinColumn(name = "idEnterprise")) })
Is it possible to expose a manytomany relationship that uses a join entity (that contains extra data columns), below is my entities;
I'm trying to get 'purchases' to show in REST, I've put in 'products' as an example of a working REST mapping;
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, targetEntity = Purchase.class, orphanRemoval = true)
#JoinColumn(name = "user_id", updatable = false)
private List<Purchase> purchases = new ArrayList<>();
#ManyToMany
#JoinColumn(name = "user_id", updatable = false)
private List<Product> products = new ArrayList<>();
}
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
}
#Entity
public class Purchase implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
#ManyToOne(targetEntity = Prodect.class)
#JoinColumn(name = "product_id", referencedColumnName = "id")
private Product product;
#Column(name = "purchase_date")
private Date purchaseDate;
}
So if i send the REST call;
[GET http://localhost:8080/webapp/users/1]
It returns links for [http://localhost:8080/webapp/users/1/products] but not for [http://localhost:8080/webapp/users/1/purchases]
worked out what the issue was; I need to create a JpaRepository for the Purchase entity. Soon as I added that, the REST links for purchases are available.