3
votes

I have a spring boot project and I use spring JPA. I have this model Receipt which has a column TransactionDate which its database column name is transaction_date. I'm calling the findAll(Predicate predicate, Pageable pageable) to get the desired data page.

It works completely fine when I create my predicate using the BooleanBuilder in my ReceiptService and passes it with the PageRequest without a sort it works fine but the moment I add a sort to it, it will throw the below exception:

org.springframework.data.mapping.PropertyReferenceException: No property transaction found for type Receipt!

and this is how I created my PageRequest

org.springframework.data.domain.Pageable pageable = new PageRequest(
        0, 
        10,
        Direction.DESC,
        "transaction_date");

and this is what my pageable looks like when I look at it in the debug mode

Page request [number: 0, size 10, sort: transaction_date: DESC]

but then from the exception it seems that it's cutting it from the _

here is my repository function: (since the conditions are coming from a search box which might have some other fields null or have a value, I realized it's easy to do it using the predicate)

public Page<Receipt> findAll(Predicate predicate, org.springframework.data.domain.Pageable pageable);

here is the Receipt Entity

@Entity
public class Receipt extends Base {

@Column(name="email")
private String Email;

@Column(name="bsid")
private String Bsid;


@Column(name="snap_shot")
private String SnapShot;

@Column(name="transaction_date")
private Date TransactionDate;

@Column(name="reference_number")
private String ReferenceNumber;

@Column(name="total_amount")
private Double TotalAmount;

@Column(name="submitted_by_user")
private boolean SubmittedByUser;

@Column(name="approval_date")
private Date ApprovalDate;

@ManyToOne
@JoinColumn(name="user_id")
private User User;

@ManyToOne
@JoinColumn(name="store_id")
private Store Store;

@Column(name="pending")
private boolean Pending;

@Column(name="declined")
private boolean Declined;

@Column(name="approved")
private boolean Approved;

public String getEmail() {
    return Email;
}

public void setEmail(String email) {
    Email = email.trim();
}

public String getBsid() {
    return Bsid;
}

public void setBsid(String bsid) {
    Bsid = bsid.trim();
}

public String getSnapShot() {
    return SnapShot;
}

public void setSnapShot(String snapShot) {
    SnapShot = snapShot.trim();
}

public Store getStore() {
    return Store;
}

public void setStore(Store store) {
    Store = store;
}

public Date getTransactionDate() {
    return TransactionDate;
}

public void setTransactionDate(Date transactionDate) {
    TransactionDate = transactionDate;
}

public String getReferenceNumber() {
    return ReferenceNumber;
}

public void setReferenceNumber(String referenceNumber) {
    ReferenceNumber = referenceNumber.trim();
}

public Double getTotalAmount() {
    return TotalAmount;
}

public void setTotalAmount(Double totalAmount) {
    TotalAmount = totalAmount;
}

public boolean isSubmittedByUser() {
    return SubmittedByUser;
}

public void setSubmittedByUser(boolean submittedByUser) {
    SubmittedByUser = submittedByUser;
}

public User getUser() {
    return User;
}

public void setUser(User user) {
    User = user;
}

public boolean isPending() {
    return Pending;
}

public void setPending(boolean pending) {
    Pending = pending;
}

public boolean isDeclined() {
    return Declined;
}

public void setDeclined(boolean declined) {
    Declined = declined;
}

public boolean isApproved() {
    return Approved;
}

public void setApproved(boolean approved) {
    Approved = approved;
}

public Date getApprovalDate() {
    return ApprovalDate;
}

public void setApprovalDate(Date approvalDate) {
    ApprovalDate = approvalDate;
}
}
3
What Happens if you use the Field name 'TransactionDate' in your pageable? - pDer666
@pDer666 then it says org.springframework.data.mapping.PropertyReferenceException: No property transactionDate found for type Receipt! - arash moeen

3 Answers

1
votes

Well, JPA in general (besides when you force the native SQL commands), expects to receive the java property name, in this case TransactionDate, instead of the real database column name transaction_date.

So to fix your code, basically, you should just make a call like:

org.springframework.data.domain.Pageable pageable = new PageRequest(
    0, 
    10,
    Direction.DESC,
    "TransactionDate");

That's being said, the java naming convention says that properties and variables should be in a lower camel case, as you can check into oracle documentation page.

I'm not sure if JPA (and in this case, spring-data), expects you to follow the naming convention as well. So if just passing the name as I told you to do so, have not worked, you probably need to change your entity to be like:

@Entity
public class Receipt extends Base {

    @Column(name="email")
    private String email;

    @Column(name="bsid")
    private String bsid;


    @Column(name="snap_shot")
    private String snapShot;

    @Column(name="transaction_date")
    private Date transactionDate;

    @Column(name="reference_number")
    private String referenceNumber;

    @Column(name="total_amount")
    private Double totalAmount;

    @Column(name="submitted_by_user")
    private boolean submittedByUser;

    @Column(name="approval_date")
    private Date approvalDate;

    @ManyToOne
    @JoinColumn(name="user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name="store_id")
    private Store store;

    @Column(name="pending")
    private boolean pending;

    @Column(name="declined")
    private boolean declined;

    @Column(name="approved")
    private boolean approved;

    // getters, setters, equals, hashcode, tostring, ...
}

And then, your call should be like:

org.springframework.data.domain.Pageable pageable = new PageRequest(
    0, 
    10,
    Direction.DESC,
    "transactionDate");

Cheers, Nikolas

0
votes

Uhmm if i understand right your problem, you want to sort all the data, and then page it, right?

You can make it with the method naming.

Page<Receipt> findAllByOrderByTransactionDateDesc(Pageable pageable); 

If this fail you can also use a query

@Query("SELECT r FROM Receipt r ORDER BY  r.transaction_date DESC")
Page<Receipt> findAllQuery(Pageable pageable);

Then on your service you pass the Pageable to call it.

Page page = myRepo.findAllByOrderByTransactionDateDesc(new PageRequest(page, size));

Page page = myRepo.findAllQuery(new PageRequest(page, size));
0
votes

Not sure if this is the right way or not but it fixed my problem for now.

So I just changed the TransactionDate in my entity to transactionDate and then changed the same column in the querydsl auto generated Q model as well (I copy pasted those classes into my models package so I can easily control them) and now it just works fine if I pass sorting column as "transactionDate".

I wouldn't mark this as an answer for few days so maybe some one would come up with the correct way of fixing this but just for a sake of some one who might have had the same issue.