Reputation: 27
I use the technologies jpa, hibernate, spring boot - data, api REST.
I have the following error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'walletRestService': Unsatisfied dependency expressed through field 'walletRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'walletRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query method public abstract java.lang.Long com.wj.dao.WalletRepository.createWallet(java.lang.Long,java.lang.String)! No property createWallet found for type Wallet!
Here is my code :
Entity user:
package com.wj.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import com.fasterxml.jackson.annotation.JsonManagedReference;
@Entity
public class User implements Serializable{
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy="user", fetch=FetchType.LAZY)
@JsonManagedReference
private List<Wallet> wallets = new ArrayList<>();
public User() {
super();
}
public User(String name) {
super();
this.name = name;
}
public User(Long id, String name) {
super();
this.id = id;
this.name = name;
}
public User(Long id, String name, List<Wallet> wallets) {
super();
this.id = id;
this.name = name;
this.wallets = wallets;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Wallet> getWallets() {
return wallets;
}
public void setWallets(List<Wallet> wallets) {
this.wallets = wallets;
}
}
Entity wallet:
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name="user_id")
@JsonBackReference
private User user;
public Wallet() {
super();
}
public Wallet(String name, User user) {
super();
this.name = name;
this.user = user;
}
public Wallet(Long id, String name, User user) {
super();
this.id = id;
this.name = name;
this.user = user;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
restApi:
@RequestMapping(value="/wallets", method=RequestMethod.POST)
public Wallet save(@RequestBody Wallet wallet) {
User user = wallet.getUser();
Long id = walletRepository.createWallet(user.getId(), wallet.getName());
User boundUser = wallet.getUser();
User simpleUser = new User(boundUser.getId(), boundUser.getName());
wallet = new Wallet(id, wallet.getName(), simpleUser);
return walletRepository.save(wallet);
}
DAO:
package com.wj.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wj.entities.Wallet;
public interface WalletRepository extends JpaRepository<Wallet, Long>{
Long createWallet(Long id, String name);
}
Upvotes: 2
Views: 33212
Reputation: 131556
This declaration in your WalletRepository
interface is not valid for Spring :
Long createWallet(Long id, String name);
How do you want that Spring guesses what the createWallet()
method is designed to create and persist a Wallet
entity with a Long id
and a String name
?
In fact the methods you declare in your WalletRepository
interface are retrieval methods that rely on naming conventions to allow Spring create the queries for you. And create
is not referenced in the Spring Data documentation :
The mechanism strips the prefixes
find…By
,read…By
,query…By
,count…By
, andget…By
from the method and starts parsing the rest of it.
As Spring didn't recognize create
, it probably tries to resolve createWallet
as a field of the entity. Whereas the message :
No property createWallet found for type Wallet!
To save an entity, instead use the method provided in the JpaRepository
:
<S extends T> S save(S entity);
which for your repository will be inferred as :
Wallet save(Wallet entity);
And adapt your client code to create the Wallet
instance and to pass it to save()
.
Such as :
@RequestMapping(value="/wallets", method=RequestMethod.POST)
public Wallet save(@RequestBody Wallet wallet) {
User boundUser = wallet.getUser();
return walletRepository.save(wallet);
}
Upvotes: 7