I have tried to use other problems brought up on this website, but none of them relate to what I am doing.
I am trying to 'deserialize' soap xml using simpleXML for an Android application. I'm getting closer and closer to getting this, but I have hit a brick wall here.
When I run my code, I get the following error:
org.simpleframework.xml.core.PersistenceException: Element 'serviceOrderCT' is already used with #org.simpleframework.xml.Element(name=, type=void, data=false, required=true) on field 'serviceOrderCT' private serviceOrderCT GetServiceOrdersResult.serviceOrderCT at line 26
So, the problem seems to be with the 'GetServiceOrdersResult.java' class (code below), but I can't put my finger on what it is.
I have been at this for hours and have gotten nowhere.
Help to get passed this problem would be appreciated.
Thanks.
[EDIT: Here's the XML File]
<GetServiceOrdersResponse xmlns="http://tempuri.org/">
<GetServiceOrdersResult xmlns:a="http://schemas.datacontract.org/2004/07/MobileWebService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:serviceOrderCT>
<a:_bill_to_Customer_No_>xxxxx</a:_bill_to_Customer_No_>
<a:_bill_to_Name>xxxxxxx</a:_bill_to_Name>
<a:_customer_No_ i:nil="true" />
<a:_description />
<a:_fix_By_Date>xxxxxxxxxxxxx</a:_fix_By_Date>
<a:_fix_By_Time />
<a:_fixed_Date>xxxxxxxxxxxx</a:_fixed_Date>
<a:_fixed_Time>xxxxxxxxxxxxxx</a:_fixed_Time>
<a:_name>xxxxxxxxxxxxxxx</a:_name>
<a:_no_>xxxxxxxxxxxxxxxxxxx</a:_no_>
<a:_order_Date>xxxxxxxxxxxxxxx</a:_order_Date>
<a:_order_Time>xxxxxxxxxxxxx</a:_order_Time>
<a:_responded_Date>xxxxxxxxxxxxxxxxxx</a:_responded_Date>
<a:_responded_Time />
<a:_response_Date>xxxxxxxxxxxxxxxxxx</a:_response_Date>
<a:_response_Time>xxxxxxxxxxxxxxxxxxxx</a:_response_Time>
<a:_transaction_Status>xxxxxxxxxxxxxxx</a:_transaction_Status>
<a:_your_Reference />
</a:serviceOrderCT>
<a:serviceOrderCT>
a:_bill_to_Customer_No_>xxxxx</a:_bill_to_Customer_No_>
<a:_bill_to_Name>xxxxxxx</a:_bill_to_Name>
<a:_customer_No_ i:nil="true" />
<a:_description />
<a:_fix_By_Date>xxxxxxxxxxxxx</a:_fix_By_Date>
<a:_fix_By_Time />
<a:_fixed_Date>xxxxxxxxxxxx</a:_fixed_Date>
<a:_fixed_Time>xxxxxxxxxxxxxx</a:_fixed_Time>
<a:_name>xxxxxxxxxxxxxxx</a:_name>
<a:_no_>xxxxxxxxxxxxxxxxxxx</a:_no_>
<a:_order_Date>xxxxxxxxxxxxxxx</a:_order_Date>
<a:_order_Time>xxxxxxxxxxxxx</a:_order_Time>
<a:_responded_Date>xxxxxxxxxxxxxxxxxx</a:_responded_Date>
<a:_responded_Time />
<a:_response_Date>xxxxxxxxxxxxxxxxxx</a:_response_Date>
<a:_response_Time>xxxxxxxxxxxxxxxxxxxx</a:_response_Time>
<a:_transaction_Status>xxxxxxxxxxxxxxx</a:_transaction_Status>
<a:_your_Reference />
</a:serviceOrderCT>
</GetServiceOrdersResult>
</GetServiceOrdersResponse>
Envelope.java
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root
public class Envelope {
#Element(name = "Body")
private Body body;
public Body getBody() {
return body;
}
}
Body.java
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Path;
import org.simpleframework.xml.Root;
import java.util.List;
public class Body {
#Element(name = "GetServiceOrdersResponse")
private GetServiceOrdersResponse getServiceOrdersResponse;
public GetServiceOrdersResponse getServiceOrdersResponse() {
return getServiceOrdersResponse;
}
}
GetServiceOrdersResponse.java
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Path;
public class GetServiceOrdersResponse {
#Element(name = "GetServiceOrdersResult")
private GetServiceOrdersResult getServiceOrdersResult;
public GetServiceOrdersResult getGetServiceOrdersResult() {
return getServiceOrdersResult;
}
}
GetServiceOrdersResult.java
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Path;
import org.simpleframework.xml.Root;
import java.util.List;
public class GetServiceOrdersResult {
#Element
private serviceOrderCT serviceOrderCT;
public serviceOrderCT getServiceOrderCT() {
return serviceOrderCT;
}
}
serviceOrderCT
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;
public class serviceOrderCT {
#Element(name = "_bill_to_Customer_No_", required = false)
private String billToCustomerNo;
#Element(name = "_bill_to_Name", required = false)
private String billToName;
#Element(name = "_customer_No_", required = false)
private String customerNo;
#Element(name = "_description", required = false)
private String description;
#Element(name = "_fix_By_Date", required = false)
private String fixByDate;
#Element(name = "_fix_By_Time", required = false)
private String fixByTime;
#Element(name = "_fixed_Date", required = false)
private String fixedDate;
#Element(name = "_fixed_Time", required = false)
private String fixedTime;
#Element(name = "_name", required = false)
private String name;
#Element(name = "_no_", required = false)
private String no;
#Element(name = "_order_Date", required = false)
private String orderDate;
#Element(name = "_order_Time", required = false)
private String orderTime;
#Element(name = "_responded_Date", required = false)
private String respondedDate;
#Element(name = "_responded_Time", required = false)
private String respondedTime;
#Element(name = "_response_Date", required = false)
private String responseDate;
#Element(name = "_response_Time", required = false)
private String responseTime;
#Element(name = "_transaction_Status", required = false)
private String transactionStatus;
#Element(name = "_your_Reference", required = false)
private String yourReference;
public serviceOrderCT() {
}
public String getBillToCustomerNo() {
return billToCustomerNo;
}
public void setBillToCustomerNo(String billToCustomerNo) {
this.billToCustomerNo = billToCustomerNo;
}
public String getBillToName() {
return billToName;
}
public void setBillToName(String billToName) {
this.billToName = billToName;
}
public String getCustomerNo() {
return customerNo;
}
public void setCustomerNo(String customerNo) {
this.customerNo = customerNo;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFixByDate() {
return fixByDate;
}
public void setFixByDate(String fixByDate) {
this.fixByDate = fixByDate;
}
public String getFixByTime() {
return fixByTime;
}
public void setFixByTime(String fixByTime) {
this.fixByTime = fixByTime;
}
public String getFixedDate() {
return fixedDate;
}
public void setFixedDate(String fixedDate) {
this.fixedDate = fixedDate;
}
public String getFixedTime() {
return fixedTime;
}
public void setFixedTime(String fixedTime) {
this.fixedTime = fixedTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getOrderDate() {
return orderDate;
}
public void setOrderDate(String orderDate) {
this.orderDate = orderDate;
}
public String getOrderTime() {
return orderTime;
}
public void setOrderTime(String orderTime) {
this.orderTime = orderTime;
}
public String getRespondedDate() {
return respondedDate;
}
public void setRespondedDate(String respondedDate) {
this.respondedDate = respondedDate;
}
public String getRespondedTime() {
return respondedTime;
}
public void setRespondedTime(String respondedTime) {
this.respondedTime = respondedTime;
}
public String getResponseDate() {
return responseDate;
}
public void setResponseDate(String responseDate) {
this.responseDate = responseDate;
}
public String getResponseTime() {
return responseTime;
}
public void setResponseTime(String responseTime) {
this.responseTime = responseTime;
}
public String getTransactionStatus() {
return transactionStatus;
}
public void setTransactionStatus(String transactionStatus) {
this.transactionStatus = transactionStatus;
}
public String getYourReference() {
return yourReference;
}
public void setYourReference(String yourReference) {
this.yourReference = yourReference;
}
}
Main.java
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import java.io.File;
public class Main {
public static void main(String[] args) {
try {
Serializer serializer = new Persister();
File result = new File("C:\\Users\\xxxxxxxx\\Documents\\file.xml");
Envelope example = serializer.read(Envelope.class, result);
System.out.println(example.getBody().getServiceOrdersResponse().getGetServiceOrdersResult().getServiceOrderCT().getBillToCustomerNo());
} catch (Exception e) {
e.printStackTrace();
}
}
}
So, I solve my problem, a day after asking for help, on my own Yet again.
You have to implement an ElementList, if you want to get all three serviceOrderCTs. It was only picking up one.
If I removed the other two, I would get something back.
Advice for anyone who reads this, stick with the official documentation. It will help you a lot. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#list
Related
Staying within JAXB how would I refactor MyNote so that it conforms to:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
Which is well formed but not valid, to my understanding. Current output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyNotes>
<Note>
<note>XY3Z1RGEO9W79LALCS</note>
<to>LJAY9RNMUGGENGNND9</to>
<from>GOVSHVZ3GJWC864L7X</from>
<heading>EX6LGVE5LGY4A6B9SK</heading>
<body>L95WYQNMEU1MFDRBG4</body>
</Note>
</MyNotes>
which is too flat, rather than nested as the example.
I believe this makes note the root element, with other elements being children nodes to note if I'm using correct terminology.
The MyNote class:
package net.bounceme.dur.jaxb.hello.world;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(propOrder = {"note", "to", "from", "heading", "body"})
#XmlRootElement(name = "note")
public class MyNote {
private String note;
private String to;
private String from;
private String heading;
private String body;
public String getNote() {
return note;
}
#XmlElement(name = "note")
public void setNote(String note) {
this.note = note;
}
public String getTo() {
return to;
}
#XmlElement(name = "to")
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
#XmlElement(name = "from")
public void setFrom(String from) {
this.from = from;
}
public String getHeading() {
return heading;
}
#XmlElement(name = "heading")
public void setHeading(String heading) {
this.heading = heading;
}
public String getBody() {
return body;
}
#XmlElement(name = "body")
public void setBody(String body) {
this.body = body;
}
#Override
public String toString() {
return note + to + from + heading + body;
}
}
The MyNotes class:
package net.bounceme.dur.jaxb.hello.world;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "MyNotes")
public class MyNotes {
private static final Logger LOG = Logger.getLogger(MyNotes.class.getName());
private List<MyNote> myNotes = new ArrayList<>();
public MyNotes() {
}
public List<MyNote> getMyNotes() {
LOG.info(myNotes.toString());
return myNotes;
}
#XmlElement(name = "Note")
public void setMyNotes(List<MyNote> myNotes) {
LOG.info(myNotes.toString());
this.myNotes = myNotes;
}
public void add(MyNote myNote) {
LOG.info(myNote.toString());
myNotes.add(myNote);
}
#Override
public String toString() {
StringBuffer str = new StringBuffer();
for (MyNote note : this.myNotes) {
str.append(note.toString());
}
return str.toString();
}
}
exercising the MyNote and MyNotes classes:
public MyNotes unmarshallMyNotesFromFile(URI uri) throws Exception {
File file = new File(uri);
JAXBContext jaxbContext = JAXBContext.newInstance(MyNotes.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyNotes myNotes = (MyNotes) jaxbUnmarshaller.unmarshal(file);
return myNotes;
}
public void marshallMyNotesAndWriteToFile(MyNotes notes, URI uri) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(MyNotes.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(notes, new File(uri));
jaxbMarshaller.marshal(notes, System.out);
}
I'm looking to grab this xml through the web; first need to match the structure to the example.
You are very close. You need to change how you name your xmlElement for myNotes in MyNotes class. Also MyNote should not have a note field itself (according to your desired xml). Your edited classes would look like this (I also removed the logging statements for my convenience):
#XmlType(propOrder = { "to", "from", "heading", "body"})
#XmlRootElement(name = "note")
public class MyNote {
private String to;
private String from;
private String heading;
private String body;
public String getTo() {
return to;
}
#XmlElement(name = "to")
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
#XmlElement(name = "from")
public void setFrom(String from) {
this.from = from;
}
public String getHeading() {
return heading;
}
#XmlElement(name = "heading")
public void setHeading(String heading) {
this.heading = heading;
}
public String getBody() {
return body;
}
#XmlElement(name = "body")
public void setBody(String body) {
this.body = body;
}
#Override
public String toString() {
return to + from + heading + body;
}
}
and MyNotes:
#XmlRootElement(name = "MyNotes")
public class MyNotes {
private List<MyNote> myNotes = new ArrayList<>();
public MyNotes() {
}
public List<MyNote> getMyNotes() {
return myNotes;
}
#XmlElement(name = "note")
public void setMyNotes(List<MyNote> myNotes) {
this.myNotes = myNotes;
}
public void add(MyNote myNote) {
myNotes.add(myNote);
}
#Override
public String toString() {
StringBuffer str = new StringBuffer();
for (MyNote note : this.myNotes) {
str.append(note.toString());
}
return str.toString();
}
}
i have to send request by soap. and i use Retrofit2.
i cant convert and deserialize the response. in type of xml like "xsi" instance "xmlns" its my problem.
this is my response
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:requestCPResponse xmlns:ns2="http://incomingwebchannel.hrz.jpos.org/">
<return xsi:type="ns2:jiringBillInqOut" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<refNo>091015900983</refNo>
<responseCode>03</responseCode>
</return>
</ns2:requestCPResponse>
</S:Body>
</S:Envelope>
and this is my retrofit interface
#POST("/nafis-web-3/services/mobile")
Call<UsStatesResponseEnvelope> requestCP(#Body UsStatesRequestEnvelope body);
this is my request code
new RequestCallback<>(activity, true, ApiClient.createApi(activity).requestCP(envelope), new RequestListener<UsStatesResponseEnvelope>() {
#Override
public void onResponse(#NonNull final Response<UsStatesResponseEnvelope> response) {
try {
com.teskaco.transactionsample.utils.Log.e(response.body().getBody().getUsStatesCPResponse().getStatesResponseReturn().getResponseCode());
} catch (Exception e) {
Log.e("TAG", e.getMessage());
}
}
#Override
public void onFailure(#NonNull int code, #NonNull JsonObject jsonObject) {
}
});
and this is my model. UsStatesResponseBody.clss
#Root(name = "S:Envelope")
#NamespaceList({
#Namespace( prefix = "S", reference = "http://schemas.xmlsoap.org/soap/envelope/")})
public class UsStatesResponseEnvelope {
#Element(name = "S:Body", required = false)
private UsStatesResponseBody body;
public UsStatesResponseBody getBody() {
return body;
}
public void setBody(UsStatesResponseBody body) {
this.body = body;
}
}
class UsStatesResponseBody.clss
#Root(name = "S:Body", strict = false)
public class UsStatesResponseBody {
#Element(name = "ns2:requestCPResponse",required = false)
private UsStatesCPResponse cpResponse;
public UsStatesCPResponse getUsStatesCPResponse() {
return cpResponse;
}
public void UsUsStatesCPResponse(UsStatesCPResponse responseReturn) {
this.cpResponse = responseReturn;
}
}
UsStatesCPResponse.clss
#Root(name = "ns2:requestCPResponse", strict = false)
#NamespaceList({
#Namespace( prefix = "ns2", reference = "http://incomingwebchannel.hrz.jpos.org/")})
public class UsStatesCPResponse {
#Element(name = "return",required = false)
private UsStatesResponseReturn responseReturn;
public UsStatesResponseReturn getStatesResponseReturn() {
return responseReturn;
}
public void UsStatesResponseReturn(UsStatesResponseReturn responseReturn) {
this.responseReturn = responseReturn;
}
}
UsStatesResponseReturn.clss
#Root(name = "return", strict = false)
#NamespaceList({
#Namespace( prefix = "xsi:type", reference = "ns2:jiringBillInqOut"),
#Namespace( prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance")
})
public class UsStatesResponseReturn {
#Element(name = "refNo",required = false)
private String refNo;
#Element(name = "responseCode",required = false)
private String responseCode;
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public String getResponseCode() {
return responseCode;
}
public void setResponseCode(String responseCode) {
this.responseCode = responseCode;
}
}
i solve with tray and error.
Parent class
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;
#Root(name = "S:Envelope" ,strict = false)
#Namespace(prefix = "S", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class BuyResponseEnvelope {
#Element(name = "Body")
private BuyResponseBody body;
public BuyResponseBody getBody() {
return body;
}
public void setBody(BuyResponseBody body) {
this.body = body;
}
}
Body class
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root(name = "S:Body" ,strict = false)
public class BuyResponseBody {
#Element(name = "requestCPResponse")
private BuyCPResponse cpResponse;
public BuyCPResponse getCpResponse() {
return cpResponse;
}
public void setCpResponse(BuyCPResponse cpResponse) {
this.cpResponse = cpResponse;
}
}
request cp class
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;
#Root(name = "ns2:requestCPResponse",strict = false)
#Namespace( prefix = "ns2", reference = "http://incomingwebchannel.hrz.jpos.org/")
public class BuyCPResponse {
#Element(name = "return")
private BuyResponseReturn responseReturn;
public BuyResponseReturn getResponseReturn() {
return responseReturn;
}
public void setResponseReturn(BuyResponseReturn responseReturn) {
this.responseReturn = responseReturn;
}
}
and return class
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
#Root(name = "return",strict = false)
#Namespace( prefix = "xsi", reference = "http://www.w3.org/2001/XMLSchema-instance")
public class BuyResponseReturn {
#Element(name = "refNo")
private String refNo;
#Element(name = "responseCode")
private String responseCode;
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public String getResponseCode() {
return responseCode;
}
public void setResponseCode(String responseCode) {
this.responseCode = responseCode;
}
}
I have 3 tables in my database.FOOD_GROUP, FOOD_DESCRIPTION, SECONDARY_FOOD_DESCRIPTION,. My Application.java parses data files in the correct order so that on table can useful to the next. My issue is that when it comes to setting the databankID field in the SecondaryFoodDescription class, I get Data truncation: Data too long for column 'food' at row 1. This is surprising (at least to me) because, I use the same repository.save method to populate the foodGroup field in the class. Food.
EDIT: I'm aware that normally, an error like Data truncation: Data too long for column 'foodid' at row 1 would mean that what I'm trying to insert is too big for a field. However, I'm trying to insert an Entity. How could my Entity be too big?
Can anyone spot what I'm wrong?
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner demo(FoodGroupRepository foodGrouprepository, FoodRepository foodRepository,
SecondaryFoodInformationRepository secondaryFoodInformationRepository,
) {
return (args) -> {
FoodGroupParser foodGroupParser = new FoodGroupParser();
FoodGroup foodGroup;
Map<String, String> foodGroupMap = foodGroupParser.returnFoodGroupData();
for (Map.Entry<String, String> entry : foodGroupMap.entrySet()) {
foodGroup = new FoodGroup(entry.getKey(), entry.getValue());
foodGrouprepository.save(foodGroup);
}
FoodDescriptionParser foodDescriptionParser = new FoodDescriptionParser();
List<String[]> listOfFooods = foodDescriptionParser.returnFoodDescriptionData();
Food foodDescription;
SecondaryFoodDescription secondaryFoodDescription;
for (String[] foodItem : listOfFooods) {
foodDescription = new Food(foodItem[0],foodGrouprepository.findOne(foodItem[1]),foodItem[2],foodItem[4],foodItem[5],foodItem[8]);
secondaryFoodDescription = new SecondaryFoodDescription();
foodRepository.save(foodDescription);
secondaryFoodDescription = new SecondaryFoodDescription(foodRepository.findOne(foodItem[0]),foodItem[6],foodItem[7],foodItem[9],foodItem[10],foodItem[11]);
secondaryFoodInformationRepository.save(secondaryFoodDescription);
}
};
}
}
Repository interfaces:
#RepositoryRestResource
public interface FoodGroupRepository extends PagingAndSortingRepository<FoodGroup,String> {
}
#RepositoryRestResource
public interface FoodRepository extends PagingAndSortingRepository<Food, String>{
List<Food> findByLongDescription(#Param("longDescription") String name);
}
#RepositoryRestResource
public interface SecondaryFoodInformationRepository extends PagingAndSortingRepository<SecondaryFoodDescription,Long> {
}
Food group entity:
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
#Entity
#Table(name = "FOOD_GROUP")
public class FoodGroup implements Serializable{
public FoodGroup(){}
public FoodGroup(String id, String foodName){
this.setFoodGroupCode(id);
this.setFoodName(foodName);
}
#Id
#NotNull
#Size(min = 4,max = 4)
private String foodGroupCode;
#NotNull
#Size(max=60)
private String foodName;
public String getFoodGroupCode() {
return foodGroupCode;
}
public void setFoodGroupCode(String foodGroupCode) {
this.foodGroupCode = foodGroupCode;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
}
Food entity:
import javax.persistence.*;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "FOOD_DESCRIPTION")
public class Food implements Serializable {
#Id
#NotNull()
#Column(name = "NUTRITION_DATA_BANK_ID")
#Size(min = 5, max = 5)
private String nutritionDatabankID;
private FoodGroup foodGroupID;
#OneToMany(mappedBy = "foodDescription", cascade = CascadeType.ALL)
private final Set<NutritionDataForSpecificFood> ndesc = new HashSet<>();
public Set<NutritionDataForSpecificFood> getNutrients() {
return Collections.unmodifiableSet(this.ndesc);
}
public void addFood(NutritionDataForSpecificFood specificFood) {
specificFood.setFoodDescription(this);
this.ndesc.add(specificFood);
}
#NotNull
#Column(name = "LONG_DESCRIPTION")
#Size(max = 200)
private String longDescription;
#Size(max = 100)
#Column(name = "COMMON_NAME")
private String commonName;
#Size(max = 65)
#Column(name = "MANUFACTURER_NAME")
private String manufacturerName;
#Size(max = 65)
#Column(name = "SCIENTIFIC_NAME")
private String scientificNameOfFood;
public Food() {
}
public Food(String nutritionDatabankID, FoodGroup foodGroupID, String longDescription, String commonName,
String manufacturerName, String scientificNameOfFood) {
this.nutritionDatabankID = nutritionDatabankID;
this.foodGroupID = foodGroupID;
this.longDescription = longDescription;
this.commonName = commonName;
this.manufacturerName = manufacturerName;
this.scientificNameOfFood = scientificNameOfFood;
}
public FoodGroup getFoodGroupID() {
return foodGroupID;
}
public void setFoodGroupID(FoodGroup foodGroupID) {
}
public String getNutritionDatabankID() {
return nutritionDatabankID;
}
public void setNutritionDatabankID(String nutritionDatabankID) {
this.nutritionDatabankID = nutritionDatabankID;
}
public String getLongDescription() {
return longDescription;
}
public void setLongDescription(String longDescription) {
this.longDescription = longDescription;
}
public String getCommonName() {
return commonName;
}
public void setCommonName(String commonName) {
this.commonName = commonName;
}
public String getManufacturerName() {
return manufacturerName;
}
public void setManufacturerName(String manufacturerName) {
this.manufacturerName = manufacturerName;
}
public String getScientificNameOfFood() {
return scientificNameOfFood;
}
public void setScientificNameOfFood(String scientificNameOfFood) {
this.scientificNameOfFood = scientificNameOfFood;
}
}
Secondary Food Info entity:
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.io.Serializable;
#Entity
#Table(name = "SECONDARY_FOOD_DESCRIPTION")
public class SecondaryFoodDescription implements Serializable {
public SecondaryFoodDescription(){}
public SecondaryFoodDescription(Food food,String refuseDescription, String refusePercentage,
String caloriesFromProteinFactor, String caloriesFromFatFactor,
String caloriesFromCarbsFactor){
this.food = food;
this.refuseDescription = refuseDescription;
this.refuseDescription = refuseDescription;
this.caloriesFromProteinFactor = caloriesFromProteinFactor;
this.caloriesFromFatFactor = caloriesFromFatFactor;
this.caloriesFromCarbsFactor = caloriesFromCarbsFactor;
}
#Id
#GeneratedValue
#Column(name = "ID")
private Long id;
public Long getId() {
return id;
}
private Food food;
#Size(max = 135)
#Column(name = "REFUSE_DESCRIPTION")
private String refuseDescription;
#Column(name = "REFUSE_PERCENTAGE")
private String refusePercentage;
#Column(name = "CALORIES_FROM_PROTEIN_FACTOR")
private String caloriesFromProteinFactor;
#Column(name = "CALORIES_FROM_FAT_FACTOR")
private String caloriesFromFatFactor;
#Column(name = "CALORIES_FROM_CARBS_FACTOR")
private String caloriesFromCarbsFactor;
public String getRefuseDescription() {
return refuseDescription;
}
public void setRefuseDescription(String refuseDescription) {
this.refuseDescription = refuseDescription;
}
public String getRefusePercentage() {
return refusePercentage;
}
public void setRefusePercentage(String refusePercentage) {
this.refusePercentage = refusePercentage;
}
public String getCaloriesFromProteinFactor() {
return caloriesFromProteinFactor;
}
public void setCaloriesFromProteinFactor(String caloriesFromProteinFactor) {
this.caloriesFromProteinFactor = caloriesFromProteinFactor;
}
public String getCaloriesFromFatFactor() {
return caloriesFromFatFactor;
}
public void setCaloriesFromFatFactor(String caloriesFromFatFactor) {
this.caloriesFromFatFactor = caloriesFromFatFactor;
}
public String getCaloriesFromCarbsFactor() {
return caloriesFromCarbsFactor;
}
public void setCaloriesFromCarbsFactor(String caloriesFromCarbsFactor) {
this.caloriesFromCarbsFactor = caloriesFromCarbsFactor;
}
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
}
You need to annotate with appropriate relations #OneToOne/#OneToMany, otherwise the complete object will be serialized and persisted as a BLOB. If the BLOB size is large you get the Data Truncation error.
"Solved" by adding a #OneToOne annotation to the field ,food in the SecondaryFoodDescription entity.
This is an unsatisfying answer though. In the Food entity there is an unannotated field for the entity FoodGroup. That field does not produce the "column to long" error.
I have to un-/marshall the following snippet
<para sizeInfoId="sizeInfo2" styleId="mono">Franz jagt im komplett verwahrlosten <protectedText>Taxi</protectedText> quer durch Bayern.</para>
My Java Model looks like this
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
#XmlType(propOrder = { AcrossParagraph.XML_ID, AcrossParagraph.XML_STYLE_ID, AcrossParagraph.XML_SIZEINFO_ID, AcrossParagraph.XML_COMMENT, AcrossParagraph.XML_CONTENT })
#XmlRootElement(name = AcrossParagraph.XML_ROOT_TAG)
public class AcrossParagraph {
public static final String XML_ROOT_TAG = "para";
public static final String XML_ID = "id";
public static final String XML_STYLE_ID = "styleId";
public static final String XML_SIZEINFO_ID = "sizeInfoId";
public static final String XML_COMMENT = "comment";
public static final String XML_CONTENT = "content";
private String id;
private String styleId;
private String sizeInfoId;
private String comment;
private String content;
#XmlAttribute(name = AcrossParagraph.XML_ID)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlAttribute(name = AcrossParagraph.XML_STYLE_ID)
public String getStyleId() {
return styleId;
}
public void setStyleId(String styleId) {
this.styleId = styleId;
}
#XmlTransient
public void setStyleId(AcrossStyle style) {
this.styleId = style.getId();
}
#XmlAttribute(name = AcrossParagraph.XML_SIZEINFO_ID)
public String getSizeInfoId() {
return sizeInfoId;
}
public void setSizeInfoId(String sizeInfoId) {
this.sizeInfoId = sizeInfoId;
}
#XmlTransient
public void setSizeInfoId(AcrossSize size) {
this.sizeInfoId = size.getId();
}
#XmlAttribute(name = AcrossParagraph.XML_COMMENT)
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
#XmlValue
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Without the inner protectedText Tag everything is working, but I don't know how to map that inner element.
I have read something about XmlAnyElement Annotation but havn't found an example for mapping something like this.
Any ideas?
Best regards,
Pascal
create new class for protectedText element:
#XmlRootElement(name = "protectedText")
class ProtectedText implements Serializable{
#XmlValue
public String value;
}
now change content property in AcrossParagraph as below:
private List<Serializable> content;
#XmlElementRef(name = "protectedText", type = ProtectedText.class)
#XmlMixed
public List<Serializable> getContent(){
return content;
}
public void setContent(List<Serializable> content){
this.content = content;
}
when you unmarshal the content list contains mix of String and ProtectedText
Good day! I'm having a problem when updating an entity. When I click the "update" button, the changes are saved. However, when I go a different page, the recently changed (or added) items are there but the old items (that should be changed or removed) are also there. Particularly the relatedTags (the name and notes are updating just fine). Why is it not persistent or permanent? Here are the models:
Tag model:
package models;
import java.sql.Timestamp;
import java.util.*;
import javax.persistence.*;
import javax.validation.*;
import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;
#Entity
public class Tag extends Model{
#Id
private int id;
#Required
#MaxLength(value=100)
#Column(unique=true)
private String name;
#MaxLength(value=200)
private String notes;
#OneToMany(cascade=CascadeType.ALL)
public List<RelatedTag> relatedTags = new ArrayList<RelatedTag>();
#Version
public Timestamp lastUpdate;
public static Finder<Integer, Tag> find = new Finder(Int.class, Tag.class);
public Tag() {
}
public Tag(String name, String notes){
this.name = name;
this.notes = notes;
}
public Tag(int id, String name, String notes, List<RelatedTag> relatedTags) {
this.id = id;
this.name = name;
this.notes = notes;
this.relatedTags = relatedTags;
}
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 String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public List<RelatedTag> getRelatedTags() {
return relatedTags;
}
public void setRelatedTags(List<RelatedTag> relatedTags) {
this.relatedTags = relatedTags;
}
public static List<Tag> all() {
return find.all();
}
public static void create(Tag tag){
tag.save();
}
public static void delete(int id){
find.ref(id).delete();
}
public static void update(int id, Tag tag) {
tag.update(id); // updates this entity, by specifying the entity ID
}
public static boolean exists(Tag newTag) {
for(Tag allTags : Tag.find.all()) {
if(allTags.getName().equals(newTag.getName()))
return true;
}
return false;
}
}
RelatedTag model
package models;
import java.sql.Timestamp;
import java.util.*;
import javax.persistence.*;
import javax.validation.*;
import play.data.Form;
import play.data.validation.Constraints.*;
import play.db.ebean.*;
import play.db.ebean.Model.Finder;
import scala.Int;
#Entity
public class RelatedTag extends Model {
#Id
public int rtID;
private int id; //same as Tag's id
private String relationship;
private String relatedNotes;
#Version
public Timestamp lastUpdate;
public RelatedTag() {}
public RelatedTag(int id, String relationship, String relatedNotes) {
this.id = id;
this.relationship = relationship;
this.relatedNotes = relatedNotes;
}
public void setId(int id){
this.id = id;
}
public void setRelationship(String relationship){
this.relationship = relationship;
}
public void setRelatedNotes(String relatedNotes) {
this.relatedNotes = relatedNotes;
}
public int getId(){
return id;
}
public String getRelationship(){
return relationship;
}
public String getRelatedNotes() {
return relatedNotes;
}
public static void create(List<RelatedTag> rt){
((Model) rt).save();
}
public static boolean exists(String tagRelated) {
for(Tag tag : Tag.find.all()) {
if(tagRelated.equals(tag.getName()))
return true;
}
return false;
}
public static RelatedTag findByLabel(String tagRelated, String relation, String relatedNotes) {
RelatedTag relatedTag = null;
for(Tag tag : Tag.find.all()) {
if(tagRelated.equals(tag.getName())) {
relatedTag = new RelatedTag(tag.getId(), relation, relatedNotes);
}
}
return relatedTag;
}
public static Tag findTag(int id) {
for(Tag tag : Tag.find.all()) {
if(id == tag.getId())
return tag;
}
return null;
}
}
And here is where the updating happens.
Form<Tag> filledForm = tagForm.fill(Tag.find.byId(id)).bindFromRequest();
Tag editedTag = RelatedTag.findTag(id);
if(filledForm.hasErrors()) {
return badRequest(editTagForm.render(user, editedTag, filledForm, tags));
}
else {
List<RelatedTag> relatedTagsAlloc = new ArrayList<RelatedTag>();
java.util.Map<String, String[]> map = request().body().asFormUrlEncoded();
String[] relatedTags = map.get("relatedTags.tag.name");
String[] relationship = map.get("relatedTags.relationship");
String[] relatedNotes = map.get("relatedTags.relatedNotes");
if (relatedTags != null) {
for (int i = 0; i < relatedTags.length; i++) {
if (RelatedTag.exists(relatedTags[i].trim().toLowerCase().replaceAll("\\s+", " "))) {
relatedTagsAlloc.add(RelatedTag.findByLabel(
relatedTags[i].trim().toLowerCase().replaceAll("\\s+", " "), relationship[i], relatedNotes[i].trim()));
} else {
Tag unknown = new Tag(relatedTags[i], "");
Tag.create(unknown);
relatedTagsAlloc.add(RelatedTag.findByLabel(
relatedTags[i].trim().toLowerCase().replaceAll("\\s+", " "), relationship[i], relatedNotes[i].trim()));
}
}
editedTag.getRelatedTags().clear();
}
editedTag.setName(filledForm.get().getName().toLowerCase().replaceAll("\\s+", " "));
editedTag.setRelatedTags(relatedTagsAlloc);
editedTag.update();
Application.log(user, editedTag, action);
writeToFile(editedTag);
return ok(summary.render(user, editedTag));
}
What have I been doing wrong? Please help me fix this I really need your guidance. Thank you very much!