问题
I'm using Spring(xml+annotations), Hibernate(annotations) in this web service project. The database relationship diagram, models, expected and actual output are given below,
Database Table relationship
Customer.java
@Entity
@Table(name="customer")
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="customer_id", unique=true, nullable =false)
long customerId;
@Column(name="name")
String name;
@Column(name="secondary_name")
String secondaryName;
@Column(name="date")
Date date;
@Column(name="address")
String address;
@Column(name="post")
String post;
@Column(name="pin")
String pin;
@Column(name="phone")
String phone;
@OneToMany(fetch=FetchType.LAZY, mappedBy="customer", cascade=CascadeType.ALL)
@JsonManagedReference
Set<Loan> loans = new HashSet<Loan>();
//constructors, getters and setters
}
Loan.java
public class Loan implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="loan_id", nullable=false, unique=true)
long loanId;
@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name="customer_id", nullable = false)
@JsonBackReference
Customer customer;
@Column(name="date", nullable=false)
Date date;
@Column(name="amount", nullable=false)
double amount;
@OneToMany(fetch=FetchType.LAZY, mappedBy="loan", cascade=CascadeType.ALL)
@JsonManagedReference
List<Item> items = new ArrayList<Item>();
//constructors, getters, setters
}
Item.java
public class Item implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="item_id", nullable=false, unique=true)
long itemId;
@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name="loan_id", nullable = false)
@JsonBackReference
Loan loan;
@Column(name="name", nullable=false)
String name;
@Column(name="weight", nullable=false)
double weight;
//constructors, setters, getters
}
Actual output:Here, customer details are not shown
{
"loanId":4,
"date":1484937000000,
"amount":10000.0,
"items":[
{
"itemId":3,
"name":"Item1",
"weight":10.0
},
{
"itemId":4,
"name":"Item2",
"weight":20.0
}
]
}
Expected output: need to display customer details also when looking for a loan
{
"loanId":4,
"customer":{
"customerId":2,
"name":"Prem",
"address":"Street,State"
},
"date":1484937000000,
"amount":10000.0,
"items":[
{
"itemId":3,
"name":"Item1",
"weight":10.0
},
{
"itemId":4,
"name":"Item2",
"weight":20.0
}
]
}
I can able to fetch the customer details from the database and fail to load it using Jackson Json. If I remove @JsonManagedReference, I end up with circular loop. If I remove @JsonBackReference, no effects in the output. Complete code at: https://github.com/liwevire/TM_Service Thanks in advance.
回答1:
Because you are using the @JsonBackReference
on the Customer
property in the Loan
entity, the Customer
object will not included in the serialization. Use the @JsonManagedReference
for the Customer
in the Loan
object and use @JsonBackReference
on the Loan
property in the Customer
entity.
This will serialize the Customer
property of your Loan
entity. But the Customer
object serialization will not contains the Loan
property. You need to pick one side of the relationship to serialize.
To allow both side, use @JsonIdentityInfo
annotation in your entity and remove the @JsonBackReference
and @JsonManagedReference
. You entities will be something like:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "customerId")
public class Customer implements Serializable {
...
}
The property
of the @JsonIdentityInfo
refer to your entity id property, for Customer
this will be customerId
. Do this for Loan
and Item
also.
回答2:
This seems pretty old but let me put my coins here as well; I would seperate the entity and model. Means;
> Client <-> Application : Models
>
> Application <-> Database : Entities
And your service layer or whatever layer you process data should make the conversion between entities and models.
- You get rid of recursion by returning data as your wish.
- You split the definitions between two different communication channels. This way you can decide what to show to your client and how to show your client as well. This will save your DB schema be exposed directly too.
- You can extend model as per your wish without touching to the DB backend.
来源:https://stackoverflow.com/questions/41778386/jackson-bidirectional-relationship-one-to-many-not-working