Product.java
package ejava.examples.ejbwar.inventory.bo;
import javax.json.bind.annotation.JsonbProperty;
import javax.json.bind.annotation.JsonbPropertyOrder;
import javax.json.bind.annotation.JsonbTransient;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* This class represents a specific product. It has been mapped to both
* the DB, XML, and JSON -- which is not that common to do and causes
* some conflict.
*
* JAX-RS originally only had to support JAXB (i.e., @Xml annotations) and
* each vendor added optional extensions to support alternate formats like
* JSON. One common approach was to apply the Xml-centric JAXB bindings to
* JSON marshaling. That is what was done by the Jackson JSON marshaler.
* Jackson also had annotations (@Json) that could override JAXB (@Xml)
* annotations. That is how things sat for < jee8.
*
* With jee8 and jax-rs 2.1, JSON-B was created and support mandated. This
* example was written before full jee8 compliance. Thus it has been annotated
* with JSOB-B annotations (@Jsonb) and Jackson (@Json) annotations so that
* it will work with both jee7 and jee8 deployments. The client will always
* be using JSON-B.
*
* The use of JAXB annotations for Json does confuse the marshaling decision
* logic. So we have to make sure we have JSON-B annotations on the class,
* and passed to the marshaling methods. Of course -- if your marshaled class
* is a true DTO, then there is much less need for overrides.
*/
@XmlRootElement(name="product", namespace=InventoryRepresentation.NAMESPACE)
@XmlType(name="product", namespace=InventoryRepresentation.NAMESPACE, propOrder={
"name",
"quantity",
"price"
})
@XmlAccessorType(XmlAccessType.PROPERTY)
@JsonbPropertyOrder({"id","name", "quantity", "price"})
@Entity
@Table(name="JAXRSINV_PRODUCT")
@NamedQueries({
@NamedQuery(name=Product.FIND_BY_NAME,
query="select p from Product p where p.name like :criteria")
})
public class Product extends InventoryRepresentation {
private static final long serialVersionUID = -4058695470696405277L;
public static final String FIND_BY_NAME = "Inventory.findProductByName";
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private int id;
@Column(name="NAME", nullable=false)
private String name;
@Column(name="QTY", nullable=true)
private Integer quantity;
@Column(name="PRICE", nullable=true)
private Double price;
@Column(name="PROTECTED_VALUE", length=36, nullable=false, updatable=false)
private String protectedValue;
public Product() {}
public Product(String name, Integer quantity, Double price) {
this.name=name;
this.quantity=quantity;
this.price=price;
}
public Product(String name) {
this(name, null, null);
}
@XmlAttribute(required=true)
public int getId() { return id;}
public void setId(int id) {
this.id = id;
}
@XmlAttribute(required=true, name="xmlName") //used both during marshal and unmarshal
@JsonbProperty("jsonName") //for json-b -- used during toJson()
@JsonProperty("jsonName") //for jackson json -- needed when server not >=jee8 mode
public String getName() { return name; }
@JsonbProperty("jsonName") //used during fromJson()
public void setName(String name) {
this.name = name;
}
@XmlElement(required=false)
public Integer getQuantity() { return quantity; }
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
@XmlElement(required=false)
public Double getPrice() { return price; }
public void setPrice(Double price) {
this.price = price;
}
@XmlTransient
@JsonbTransient
public String getProtectedValue() { return protectedValue; }
@JsonbTransient
@JsonIgnore //for jackson json -- when < jee8 or overriding JAXB annotation
public void setProtectedValue(String protectedValue) {
this.protectedValue = protectedValue;
}
public Product withProtectedValue(String string) {
setProtectedValue(string);
return this;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Product [id=").append(id)
.append(", name=").append(name)
.append(", quantity=").append(quantity)
.append(", price=").append(price)
.append(", protectedValue=")
.append(protectedValue).append("]");
return builder.toString();
}
}