How can I send JPA generated entities over an JAX WS web service without getting the
an XML infinite cycle exception because of the cycle of references in those entities?
Any idea? I found this MOXy that can do it...partially. But i already have the entities generated and to manually add XmlTransient and such annotations to each of them it's crazy.
Do you have any other idea how to do it?
Thanks!
EclipseLink JAXB (MOXy) can handle this with its bidirectional mapping with #XmlInverseReference:
import javax.persistence.*;
#Entity
public class Customer {
#Id
private long id;
#OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
private Address address;
}
and
import javax.persistence.*;
import org.eclipse.persistence.oxm.annotations.*;
#Entity
public class Address implements Serializable {
#Id
private long id;
#OneToOne
#JoinColumn(name="ID")
#MapsId
#XmlInverseReference(mappedBy="address")
private Customer customer;
}
For more information see:
http://bdoughan.blogspot.com/2010/07/jpa-entities-to-xml-bidirectional.html
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/JPA
You can also use MOXy's externalized representation of the metadata for this. For more information see:
XML to Java mapping tool - with mapping descriptor
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
make your getCustomer #XmlTransient
#XmlTransient
public Customer getCustomer() {
...
Related
Is it possible to implement Pattern querying with JPA Criteria API?
In my case, regex patterns are stored into a quick bag property; and I'm trying to avoid using native queries (e.g. PostgreSQL POSIX support).
#Entity #Table(name = "rcp")
public class Recipient {
#Id #Column(name = "rcp_email_id")
#Email
private String email;
#CollectionTable(joinColumns = #JoinColumn(name = "rcp_email_fk"))
#ElementCollection(fetch = EAGER)
#Convert(converter = PatternConverter.class)
private Set<Pattern> rules = new HashSet<>();
...
}
So I figured I could use the Criteria API but failed to properly develop the technlogy, obviously:
#AllArgsConstructor
public class RecipientSpecification implements Specification<Recipient> {
private String sample;
#Override
public Predicate toPredicate(Root<Recipient> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.exists(root.join("rules").as(Pattern.class).matcher(sample).find());
}
}
I thought I could work on the join with a cast and execute the Java Pattern logic by casting the properties, which I realize to be dumb now because it has no sense from the JPA DSL point of view. It doesn't even compile! But is there a proper way to proceed?
Thanks in advance
I'm really new to apache cordova, I'm actually using visual studio dev kit for Cordova, I have a Java EE aplication running on glassfish and I have this web service:
import java.util.List;
import javax.ejb.EJB;
import javax.jws.WebMethod;
import javax.jws.WebService;
#WebService(serviceName = "Eventos")
public class Eventos {
#EJB
private ServiceEventoFacadeLocal ejbRef;
#WebMethod(operationName = "findAll")
public List<ServiceEvento> findAll() {
return ejbRef.findAll();
}
}
And this is the Entity:
#Entity
public class ServiceEvento implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 100)
private String nombre;
#Basic(optional = false)
#NotNull
private BigInteger precioentrada;
#Basic(optional = false)
#NotNull
private BigInteger capacidad;
#Temporal(TemporalType.TIMESTAMP)
private Date inicio;
#Size(max = 300)
private String descripciĆ³n;
#Size(max = 150)
private String ubicacion;
So as it says in the title I'm using apache cordova with visual studio, as far as my understanding goes i need to use JavaScript to call the web service,
but I don't really understand how to call the webservice in JS and after traverse the list and display it
Thanks in advance
If you are new to JavaScript, you should spend some time getting familiar with basic concepts like the XMLHttpRequest object which is what is used to call web services. After you have a base understanding, you will want to pick a client side JavaScript framework that makes dealing with both it and creating good UI easier. Ionic is a popular one right now that is worth a look and sits on top of AngularJS which is hugely popular. You may also find Monaca's OnsenUI interesting.
There is an Ionic and Monaca VS template you can use to create a project and you can also find video courses at PluralSight.
The Tools for Apache Cordova AngularJS todo app may also be of interest.
Finally, you may find BreezeJS interesting since it has some features designed to integrate with Hibernate backed POJOs and integrates well with Angluar.
i'm having problems transfering a custom object to the client. How can i transfer a custom object to the client and receive it back to the webservice? i'm transferring a file by chunks. i want to know how i should write my client. i tried passing it as MediaType.APPLICATION_JSON in client but i get no result meaning it doesn't get passed back to the webservice. Below is a bit of code im working on.
Webservice
#POST
#Path("/fileTransfer")
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public final TransferInfomation transferInfo(final FileModel file)
{
...
}
...(some code)(lets just say a syso)
FileModel Class
public class FileModel {
private String fileID;
private DataHandler dataHandler;
/**
* Constructor.
*/
public FileModel() {
}
(lets assume setters and getters are made)
(Not sure if the webservice is correct). Still learning REST, i want to know how the client should be.
thanks in advance.
A good way to "marshal" and "unmarshal" "custom objects" (in JSON, XML, etc.) in Jersey is to use JAXB (https://jaxb.java.net/).
To do this you need to create a "jaxb class", with the proper getters and setters (and annotations), e.g.:
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class FileModel{
private String fileID;
private DataHandler dataHandler;
public String getFileID(){
return fileID;
}
public void setFileID(String fileID){
this.fileID = fileID;
}
public DataHandler getDataHandler(){
return dataHandler;
}
public void setDataHandler(DataHandler dataHandler){
this.dataHandler = dataHandler;
}
}
Do not forget to declare the #XmlRootElement. Then you can simply declare and use these objects in your API endpoints (methods):
#POST
#Path("/fileTransfer")
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public final FileModel transferInfo(FileModel file)
{
// read file in "FileModel" format
// ... make several operations
// return new FileModel (or another format if you will)
}
This should work. Make sure you follow the data structure defined for FileModel correctly in the client side. See here a example on how to handle that in Jersey: How do I POST a Pojo with Jersey Client without manually convert to JSON? (where JAXB is also used).
Your REST endpoint indicates you want to consume and produce JSON. So the REST client needs to send JSON that can be deserialized into FileModel, and the TransferInfomation returned by transferInfo needs to be serialized into JSON to return to the client.
Typically, Java REST frameworks like RESTEasy, Restlet, Camel, and Spring MVC provide facilities that let you define a JSON serializer/deserializer like Jackson and the mapping rules from JSON <--> Java, and the framework handles the details for you.
So if you use one of these frameworks, you will just have to configure them to use the preferred JSON tool and define the rules.
You can achive this like below:
Server Side:
#PUT
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public String addRecord(CustomClass mCustomClass)
{
///
///
///
return "Added successfully : "+CustomClass.getName();
}// addRecord
Client Side:
public static void main(String[] args)
{
///
///
///
CustomClass mCustomClass = new CustomClass();
Client client = ClientBuilder.newClient();
String strResult = client.target(REST_SERVICE_URL).request(MediaType.APPLICATION_XML).put(Entity.xml(mCustomClass), String.class);
}
I am using the Jersey 2.1 API to return lists of JAXB annotationed objects.
I have a class Person
#XmlRootElement(name = "person")
public class Person { ...
In the Jersey API, when I return a List of Person and have the output set to xml, it creates a wrapper called <People> around my list:
<People>
<Person>
.. fields
</Person>
</People>
when I set the output to JSON format it does not add this extra People wrapper and I would like it to. I am using EclipseLink Moxy as the JSON provider. Is there a way to get the JSON output to look the same as the XML?
I came across a field for the Jersey 1.X API called FEATURE_XMLROOTELEMENT_PROCESSING that is supposed to enable this, but I don't know how to set this in 2.x. And the fact that it is doing it for XML output seems to indicate that it is already set. I just need to get the JSON to be the same!
Any help would be appreciated, thanks!
You could do the following:
Java Model
You could introduce a new class called People into your object model.
People
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement(name="People")
#XmlAccessorType(XmlAccessType.FIELD)
public class People {
#XmlElementRef
private List<Person> person;
}
Person
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="Person")
public class Person {
}
RESTful Service
Instead of:
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Person> read() {
You would do:
#GET
#Produces(MediaType.APPLICATION_JSON)
public People read() {
By default MOXy won't included the root element. When working with Jersey you can leverage the MoxyJsonConfig object (see: http://blog.bdoughan.com/2013/06/moxy-is-new-default-json-binding.html).
import javax.ws.rs.ext.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;
#Provider
public class MOXyJsonContextResolver implements ContextResolver<MoxyJsonConfig> {
private final MoxyJsonConfig config;
public MOXyJsonContextResolver() {
config = new MoxyJsonConfig()
.setIncludeRoot(true);
}
#Override
public MoxyJsonConfig getContext(Class<?> objectType) {
return config;
}
}
You can also leverage MOXy's MOXyJsonProvider class to do the same configuration:
http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html
I am trying to implement a three-way join relationship in JPA 2.0 (using annotations).
My domain is as follows:
I had a look at the #JoinTable annotation and I am not sure how to use it in order to implement the relationship.
Can anyone please provide clues or code samples?
If I understand your question well, you actually have another Entity, let's call it AdvertisementAssignment. Then, this entity should have OneToOne association with each of your 3-way counterparts.
#Entity
#Table(name = "ADV_ASSIGNMENTS")
public class AdvertisementAssignment {
private Advertisement advertisement;
private TimeSlot timeSlot;
private Day day;
// other properties definition (e.g. id, assigner etc.)
// define constructor
#OneToOne(cascade = CascadeType.ALL)
public Advertisement getAdvertisement() {
return this.advertisement;
}
public void setAdvertisement(Advertisement advertisement) {
this.advertisement = advertisement;
}
// same for 'timeSlot' and 'day' properties
}