我使用Java / Spring网络应用程序,它包含3个实体。下面提供了MySQL模式,
正如我们所见,有3个实体和各自的用户表,status和wallet_info。下面提供了3个实体,
@Entity
@Table(name = "wallet_info")
public class WalletInfo {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "code")
private String code;
@NotNull
@Column(name = "address")
private String address;
@NotNull
@Column(name = "currency")
private String currency;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "wallet_id")
Set<Status> statuses = new HashSet<>(0);
public Long getId() {
return id;
}
public WalletInfo(@NotNull String name, @NotNull String address, @NotNull String currency) {
this.code = name;
this.address = address;
this.currency = currency;
}
public WalletInfo(@NotNull String name, @NotNull String address) {
this.code = name;
this.address = address;
}
public WalletInfo() {
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public Set<Status> getStatuses() {
return statuses;
}
public void setStatuses(Set<Status> statuses) {
this.statuses = statuses;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof WalletInfo)) return false;
WalletInfo that = (WalletInfo) o;
if (!getId().equals(that.getId())) return false;
if (!getCode().equals(that.getCode())) return false;
if (!getAddress().equals(that.getAddress())) return false;
return getCurrency().equals(that.getCurrency());
}
@Override
public int hashCode() {
int result = getId().hashCode();
result = 31 * result + getCode().hashCode();
result = 31 * result + getAddress().hashCode();
result = 31 * result + getCurrency().hashCode();
return result;
}
@Override
public String toString() {
return "WalletInfo{" +
"id=" + id +
", code='" + code + '\'' +
", address='" + address + '\'' +
", currency='" + currency + '\'' +
'}';
}
}
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "id", unique = true, nullable = false)
@NotNull
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotNull
@Column(name = "name")
@Size(min = 5, max = 45, message = "Name must be between 5 and 45 characters.")
private String name;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user_id")
Set<Status> statuses = new HashSet<Status>(0);
public User() {
}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public User(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Status> getStatuses() {
return statuses;
}
public void setStatuses(Set<Status> statuses) {
this.statuses = statuses;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
if (getId() != user.getId()) return false;
return getName().equals(user.getName());
}
@Override
public int hashCode() {
int result = getId();
result = 31 * result + getName().hashCode();
return result;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
@Entity
@Table(name = "status")
public class Status {
@Id
@Column(name = "id", unique = true, nullable = false)
@NotNull
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@NotNull
@Column(name = "balance")
private float balance;
@NotNull
@Column(name = "address")
@Size(min = 5, max = 90, message = "Address must be between 5 and 90 characters.")
private String address;
@NotNull
@Column(name = "transaction")
@Size(min = 5, max = 90, message = "Transaction history must be between 5 and 90 characters.")
private String transaction;
@NotNull
@Column(name = "user_id")
@JoinColumn(table = "user", name = "id", nullable = false)
private int user_id;
@NotNull
@JoinColumn(name = "id", table = "wallet_id", nullable = false)
@Column(name = "wallet_id")
private long wallet_id;
public Status() {
}
public Status(float balance, String transaction, String address, int user_id) {
this.user_id = user_id;
this.balance = balance;
this.address = address;
this.transaction = transaction;
}
public Status(int id, int user_id, float balance, String address, String transaction) {
super();
this.id = id;
this.user_id = user_id;
this.balance = balance;
this.address = address;
this.transaction = transaction;
}
public int getId() {
return id;
}
public int getUser_id() {
return user_id;
}
public float getBalance() {
return balance;
}
public String getAddress() {
return address;
}
public String getTransaction() {
return transaction;
}
public long getWallet_id() {
return wallet_id;
}
public void setId(int id) {
this.id = id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public void setBalance(float balance) {
this.balance = balance;
}
public void setAddress(String address) {
this.address = address;
}
public void setTransaction(String transaction) {
this.transaction = transaction;
}
public void setWallet_id(long wallet_id) {
this.wallet_id = wallet_id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Status)) return false;
Status status = (Status) o;
if (id != status.id) return false;
if (user_id != status.user_id) return false;
if (Float.compare(status.balance, balance) != 0) return false;
if (!address.equals(status.address)) return false;
return transaction.equals(status.transaction);
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + user_id;
result = 31 * result + (balance != +0.0f ? Float.floatToIntBits(balance) : 0);
result = 31 * result + address.hashCode();
result = 31 * result + transaction.hashCode();
return result;
}
@Override
public String toString() {
return "Status{" +
"id=" + id +
", user_id=" + user_id +
", balance=" + balance +
", address='" + address + '\'' +
", transaction='" + transaction + '\'' +
'}';
}
}
当我命令使用cURL
curl -X GET http://localhost:8080/rest/wallet/wallets | json
时,我得到了outoput,
[
{
"id": 63,
"code": "BTC",
"address": "n2F2QEKk6Fqqk2yMTope5MYp1RtpT949ke",
"currency": "Bitcoin",
"statuses": []
},
{
"id": 64,
"code": "BTC",
"address": "mrkdfp6qoVN3YiyJhq6nXPvgr3f7YpkS9j",
"currency": "Bitcoin",
"statuses": []
},
{
"id": 65,
"code": "BTC",
"address": "n3VGaHLFx8KkpNDNHsGGcHWgMWyUoA3Qdm",
"currency": "Bitcoin",
"statuses": []
},
// some data
]
终端没有错误,但statuses
作为空列表。在WalletInfo
课程中,当我更改FetchType
LAZY
时
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "wallet_id")
Set<Status> statuses = new HashSet<>(0);
我收到错误消息
100 404 0 404 0 0 760 0 --:--:-- --:--:-- --:--:-- 760
json: error: input is not JSON: Expected ':' instead of '}' at line 7, column 1:
} ]{
^
[ {
"id" : 1,
"code" : "BTC",
"address" : "mp51mPC38Wtcmybdyd9MPEB2bKnw6eYbCs",
"currency" : "Bitcoin",
"statuses"
} ]{
"msg" : "failed to lazily initialize a collection of role: mobi.puut.entities.WalletInfo.statuses, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->mobi.puut.entities.WalletInfo[\"statuses\"])",
"date" : "2017-09-06T03:53:052Z"
}
为什么FetchType.LAZY
和FetchType.EAGER
会产生这种差异?