Spring JPA repository methods stopped working - java

Following are the classes and repository
Problem: First three methods of my repository are not working, first two were working fine initially but once i got error in saving my object due to missing AUTO INCREMENT in my database table,so i added that but than these methods stopped working.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'cststudent0_.id' in 'field list'
I have tried the solution of others having same exception but nothing work also i want to understand the reason what is actually going on. I am using spring JPA with MySQL.
UPDATED: I have tried few more common methods like findOne() and findAll() they are also not working, i think the returned type with CSTStudent (i.e. my entity) is causing this exception.
#Entity
#Table(name = "course_section_teacher")
public class CourseSectionTeacher implements java.io.Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToOne
private Course course;
#OneToOne
private Section section;
#OneToOne
private Teacher teacher;
//getter setter
}
#Entity
#Table(name = "cst_student")
public class CSTStudent implements java.io.Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToOne
private CourseSectionTeacher courseSectionTeacher;
#OneToOne
private Student student;
//getter setter
}
public interface CSTStudentRepository extends CrudRepository<CSTStudent, Long> {
List<CSTStudent> findByStudent(Student student);
List<CSTStudent> findByStudentId(long studentId);
#Query("Select csts FROM CSTStudent csts inner join csts.student s inner join csts.courseSectionTeacher cst "
+ "where s.id = :studentid and cst.id = :cstid")
CSTStudent findUsingStudentAndCourseSectionTeacher(#Param(value="studentid") long studentid,#Param(value="cstid") long cstid);
#Query("Select csts.courseSectionTeacher FROM CSTStudent csts inner join csts.student s where s.id = :studentid")
List<CourseSectionTeacher> findStudentCourses(#Param(value="studentid") long studentid);
}

Related

How to fix the most common LazyInitializationException - Hibernate JPA

I'm struggling with LazyInitializationException. I've read so far literally every article about that, but unfortunately I didn't find solution for my problem. Many of those solutions using EntityManager or things which I don't using. I'm connecting with my DB via JPA.
I've got couple of entities, but the problem is just with two of them: Order and OrderDetails.
When I get from DB object Order, and then I'll try to do order.getOrderDetails() then I gettin following error:
Exception:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.tradesystem.order.Order.orderDetails, could not initialize proxy - no Session
but it works the other way around: from OrderDetails object I can get Order by objectDetail.getOrder() .
What's more: I can't use Eager loading due to fact that I'm using it in another entity.
Here's my Order class:
#Entity
#Data
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "order_id")
private Long id;
private LocalDate date;
#OneToMany(mappedBy = "order")
private List<OrderDetails> orderDetails;
#ManyToOne
#JoinColumn(name = "buyer_fk")
private Buyer buyer;
#ManyToOne
#JoinColumn(name = "supplier_fk")
private Supplier supplier;
}
OrderDao:
#Repository("orderDao")
public interface OrderDao extends JpaRepository<Order, Long> {
#Query(value = "SELECT * FROM orders " +
"WHERE MONTH(orders.date) = ?1 AND YEAR(orders.date) = ?2",
nativeQuery = true)
List<Order> getMonthOrders(int month, int year);
}
and OrderDetails:
#Entity
#Data
#Table(name = "orderDetails")
public class OrderDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "order_details_id")
private Long id;
private BigDecimal quantity;
private BigDecimal sum;
#ManyToOne
#JoinColumn(name = "order_fk")
private Order order;
#ManyToOne
#JoinColumn(name = "product_fk")
private Product productType;
#OneToOne
#JoinColumn(name = "order_comment_fk")
private OrderComment orderComment;
}
Relationship that finished with #Many is Lazy loaded by default, so why it doesn't load my OrderDetails when I doing .getOrderDetails() ?
I will be really gratefull for any help!
PS. I'm begginer, so if I didn't explain something enough good, don't hestitate to make some questions.
Use this
#Repository("orderDao")
public interface OrderDao extends JpaRepository<Order, Long> {
#Query(value = "SELECT orders FROM Order orders LEFT JOIN FETCH orders.orderDetails " +
"WHERE MONTH(orders.date) = ?1 AND YEAR(orders.date) = ?2")
List<Order> getMonthOrders(int month, int year);
}
I have solved that problem. I was running everything in CommandLineRunner. Lazy Exception disappeared when I started making tests insted of "trying something" in main class.
My main class looked like:
#Bean
public CommandLineRunner bookDemo(OrderDao orderDao, PriceDao priceDao, ProductDao productDao,
OrderService orderService, InvoiceDao invoiceDao, InvoiceService invoiceService) {
OrderService orderService, InvoiceDao invoiceDao, InvoiceService invoiceService,
ReportService reportService) {
return (args) -> {
List<Order> orders = orderDao.findByBuyerId(1L);
for (Order order : orders) {
orderService.payForOrde(order);
}

Error in filtering by child object in Spring Data JPA Query

My code structure looks like the following.
Article:
#Entity
public class NewsArticle{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
[Other class properties such as title, publisher, publishedDate, etc.]
#OneToMany(mappedBy = "article")
private Set<UserReadNewsArticle> userReadNewsArticles = new HashSet<>();
[Getters and Setters]
}
Article read by User:
#Entity
public class UserReadNewsArticle {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private Long readAccountId;
private Long readArticleId;
#JsonIgnore
#ManyToOne
private Account account;
#JsonIgnore
#ManyToOne
private NewsArticle article;
[Getters and Setters]
}
Account:
#Entity
public class Account {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
[Other class properties]
#OneToMany(mappedBy = "account")
private Set<UserReadNewsArticle> userReadNewsArticles = new HashSet<>();
[Getters and Setters]
}
I want to have a query method in my NewsArticleRepository to get all the Read News Articles for a user.
public interface NewsArticleRepository extends PagingAndSortingRepository<NewsArticle, Long>{
Collection<NewsArticle> findByUserReadNewsArticlesReadAccountId(Long readAccountId);
}
This method works great. But how can I write a Spring Data JPA Query/Method to get the "Unread News Articles for a user". What I have tried is the following.
Collection<NewsArticle> findByUserReadNewsArticlesReadAccountIdNot(Long readAccountId);
This one does return a list of articles which have been read by other users. But my requirement is to get all the unread news articles. I have gone through Spring Data JPA Documentation but failed to come up with an easier soultion. How can I overcome this issue? Or am I doing something wrong?
You could achieve your result by using a JPQL query with also a subquery:
public interface NewsArticleRepository extends PagingAndSortingRepository<NewsArticle, Long> {
#Query("SELECT n FROM NewsArticle n WHERE n NOT IN "
+ "(SELECT ur.article FROM UserReadNewsArticle ur JOIN ur.account a WHERE a.id = :readAccountId)")
Collection<NewsArticle> findByUserReadNewsArticlesReadAccountIdNotIn(#Param("readAccountId") Long readAccountId);
}
http://localhost:8080/newsArticles/search/findByUserReadNewsArticlesReadAccountIdNotIn?readAccountId=1
So first get the read articels from the current user and then exlude them from the whole article list.
I don't think that spring data is able to get you the same, since a subquery is definitetly needed. If I'm wrong, somebody can correct me.

Hibernate generating a query from Named Query that joins on the wrong column?

I am using named query (hibernate 4).Entity defined as below.
#Entity
#NamedQuery(
name = "findAllProduct",
query = "SELECT PC.pincode,PO.description"
+" FROM PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION PVPOL"
+" INNER JOIN PVPOL.paymentId PID"
+" INNER JOIN PVPOL.pincode PC"
+" INNER JOIN PVPOL.paymentOptions PO"
+" where PVPOL.id = :id"
)
public class PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION extends baseEntity.Entity {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name="Payment_Id")
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="id")
private Set<Product_Catalog_Vendor> paymentId;
#Column(name="pincode_id")
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="pincode_id")
private Set<Pincodes> pincode;
#Column(name = "payment_options")
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="paymentOptions")
private Set<Payment_Options> paymentOptions;
//Protected setter getter here
}
Hibernate generating below sql:-
select pincode2_.pincode as col_0_0_, paymentopt3_.Description as col_1_0_
from PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION product_ve0_
inner join Product_Catalog_Vendor paymentid1_
on product_ve0_.id=paymentid1_.Id
inner join Pincodes pincode2_
on product_ve0_.id=pincode2_.pincode_id
inner join payement_options paymentopt3_
on product_ve0_.id=paymentopt3_.payment_options
where product_ve0_.id=?
Instead of
select pincode2_.pincode as col_0_0_, paymentopt3_.Description as col_1_0_
from PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION product_ve0_
INNER JOIN product_catalog_vendor paymentid1_
ON **product_ve0_.payment_id = paymentid1_.id**
INNER JOIN PINCODES pincode2_
ON **product_ve0_.pincode_id = pincode2_.pincode_id**
INNER JOIN payement_options paymentopt3_
ON **product_ve0_.payment_options=paymentopt3_.payment_options**
where product_ve0_.id=1;
Product_catalog_vendor class:
#Entity
public class Product_Catalog_Vendor extends baseEntity.Entity {
#Id
#Column(name="Id")
private int id ;
//Setters and getters here
}
Pincodes Entity:
#Entity
public class Pincodes extends baseEntity.Entity {
#Id
private int pincode_id;
#Column(name="pincode")
private int pincode;
//Setters and getters here
}
payment_options Entity below:
#Entity
#Table(name="payement_options")
public class Payment_Options extends baseEntity.Entity {
#Id
#Column(name="payment_options")
private int paymentOptions;
//Setter getter
}
I have searched on many sites but unable to find the cause behind the scene. Please give me suggestions if i am doing something wrong. some good references would be appreciated. Thanks
just to get your problem correcty, your query joins on paymentid1_.Id instead of paymentid1_.id? or am I missing the differenz between the expected and the real query?
I'm not a pro but just guessing I would say your query is joining to the id of the Product_Catalog_Vendor:
#Id
#Column(name="Id")
private int id ;
so because thats why its Id and not id...
I think you don't need mappedBy at all due to unidirectional mapping or,anyway ,you are using them in a weird way.
mappedBy is necessary only if association is bidirectional (not your case) and should refers to a field which type is of the same type of entity where mappedBy is declared (and not a String type like in your case).You used mappedBy in a way like referencedColumnName property
In your example:
#Entity
public class Product_Catalog_Vendor extends baseEntity.Entity {
#ManyToOne
private PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION pvpol;
}
and
public class PRODUCT_VENDOR_PAYMENT_OPTION_LOCATION extends baseEntity.Entity {
#Column(name="Payment_Id")
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="pvpol")
private Set<Product_Catalog_Vendor> paymentId;
}

How do I avoid NullPointerException with OneToOne mapping against a parent entity class?

I have searched and found similar issues, but they don't quite seem to be the same problem as
Why am I getting this NullPointer exception?
OneToOne Mapping with hibernate/JBoss/Seam
ANN-613 - NPE when mappedBy property is wrong on a #OneToOne
ANN-558 - #OneToMany(mappedBy="") can not recognize properties in parent classes
Hibernate Users - NPE with #Id on #OneToOne
I have a few entities mapped like this:
Person
|
+--User
I want to add a new entity PersonPartDeux with a OneToOne mapping to Person. The resulting mapping should look something like this:
Person + PersonPartDeux
|
+--User
When I do so, a NullPointerException is thrown while trying to load the mapping:
java.lang.NullPointerException
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:135)
How do I specify the mapping so I can avoid this exception?
Here's my code:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public abstract class Person implements Serializable
{
#Id
#GeneratedValue
public Long id;
#Version
public int version = 0;
public String name;
#OneToOne(cascade = CascadeType.ALL)
#PrimaryKeyJoinColumn
public PersonPartDeux personPartDeux;
}
#Entity
public class PersonPartDeux implements Serializable
{
#Id
#GeneratedValue(generator = "person-primarykey")
#GenericGenerator(
name = "person-primarykey",
strategy = "foreign",
parameters = #Parameter(name = "property", value = "person")
)
public Long id = null;
#Version
public int version = 0;
#OneToOne(optional=false, mappedBy="person")
public Person person;
public String someText;
}
#Entity
#PrimaryKeyJoinColumn(name = "person_Id")
public class User extends Person
{
public String username;
public String password;
}
As for why I'm bothering, I need both the inheritance and the OneToOne mapping to solve different known issues in my application.
Attach the Hibernate source to your project, so you can click thru or 'Open Type' (Ctrl-Shift-T in Eclipse) to view the OneToOneSecondPass source.
Seeing the source, will give you a clear indication as to what needs to be specified.
In my source (Hibernate 4.1.7), line 135 is
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
However you're probably using an earlier version.
Looking at the mappings, I'm suspicious of the #OneToOne definition -- mappedBy="person".
#OneToOne(optional=false, mappedBy="person")
public Person person;
What does it usefully mean, to map an association property by itself? Hibernate already knows the property is a OneToOne -- you just told it that.
Pointing the underpinning mapping/ FK of the property, at itself.. probably isn't actually telling Hibernate any correct or useful information.
Here's an example from the HB dosc, perhaps showing better how to do what you want:
#Entity
class MedicalHistory implements Serializable {
#Id Integer id;
#MapsId #OneToOne
#JoinColumn(name = "patient_id")
Person patient;
}
#Entity
class Person {
#Id #GeneratedValue Integer id;
}
Source: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
(3.5 docs off JBoss site.)
Cheers, hope this helps.

Hibernate inheritance, Collections and #OrderedBy superclass attribute generates MySQL syntax Error

I' using Hibernate 3.6.1 to map three entities
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
public class Entry {
private Long id;
private Date publishedAt;
#Id
public getId() {...}
...
}
#Entity
public class Category {
private Long id;
List<Podcast> podcasts;
#Id
public getId() {...}
#OneToMany(mappedBy = "category", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#OrderBy("publishedAt")
public List<Podcast> getPodcasts() {
return podcasts;
}
}
and
#Entity
public class Podcast extends Entry {
private Category category;
#ManyToOne(fetch = FetchType.EAGER)
public PodcastsCategory getCategory() {
return category;
}
}
If i try to fetch a Category instance, i get an Exception
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'podcasts0_.Entry.publishedAt' in 'order clause'
What causes this exception? Whats wrong with this mapping?
It's caused by the following bug: HHH-3577 Wrong SQL in order by clause when using joined subclasses.
As a workaround you can remove #OrderBy and fetch = FetchType.EAGER on podcasts and load category using the following query instead of get():
SELECT DISTINCT c
FROM Category c LEFT JOIN FETCH c.podcasts p
WHERE c.id = ?
ORDER BY p.publishedAt
You could try the annotation #MappedSuperClass. See section 2.2.4.4. Inherit properties from superclasses of the hibernate documentation.

Categories