How to change form data body feign client interceptor - spring

I have some api with content-type: form-data.
Every request have some common field in the body
Here is my code
package com.example.demo.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class CreateNhanhProductRequest {
private String nuctk;
private Long storeId;
private String name;
private Integer typeId;
private String parentIdName;
private Long parentId;
private String code;
private String barcode;
private BigDecimal importPrice;
private BigDecimal vat;
private BigDecimal price;
private BigDecimal wholesalePrice;
private BigDecimal oldPrice;
private Integer status;
private Object multiUnitItems;
private Object comboItems;
private Long categoryId;
private Long internalCategoryId;
private Long brandId;
private Double shippingWeight;
private String unit;
private Integer length;
private Integer width;
private Integer height;
private Long countryId;
private Long warrantyAddress;
private String warrantyPhone;
private Long warranty;
private String warrantyContent;
private Integer firstRemain;
private Integer importType;
private Long depotId;
private String supplierName;
private Long supplierId;
private Integer checkcopyImg;
private Integer attributeCombinated;
private String metaTitle;
private String metaDescription;
private Object metaKeywords;
private Object tags;
#JsonProperty("tag-suggest")
private Object tagSuggest;
public String getNuctk() {
return nuctk;
}
public void setNuctk(String nuctk) {
this.nuctk = nuctk;
}
public Long getStoreId() {
return storeId;
}
public void setStoreId(Long storeId) {
this.storeId = storeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getTypeId() {
return typeId;
}
public void setTypeId(Integer typeId) {
this.typeId = typeId;
}
public String getParentIdName() {
return parentIdName;
}
public void setParentIdName(String parentIdName) {
this.parentIdName = parentIdName;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public BigDecimal getImportPrice() {
return importPrice;
}
public void setImportPrice(BigDecimal importPrice) {
this.importPrice = importPrice;
}
public BigDecimal getVat() {
return vat;
}
public void setVat(BigDecimal vat) {
this.vat = vat;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public BigDecimal getWholesalePrice() {
return wholesalePrice;
}
public void setWholesalePrice(BigDecimal wholesalePrice) {
this.wholesalePrice = wholesalePrice;
}
public BigDecimal getOldPrice() {
return oldPrice;
}
public void setOldPrice(BigDecimal oldPrice) {
this.oldPrice = oldPrice;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Object getMultiUnitItems() {
return multiUnitItems;
}
public void setMultiUnitItems(Object multiUnitItems) {
this.multiUnitItems = multiUnitItems;
}
public Object getComboItems() {
return comboItems;
}
public void setComboItems(Object comboItems) {
this.comboItems = comboItems;
}
public Long getCategoryId() {
return categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
}
public Long getInternalCategoryId() {
return internalCategoryId;
}
public void setInternalCategoryId(Long internalCategoryId) {
this.internalCategoryId = internalCategoryId;
}
public Long getBrandId() {
return brandId;
}
public void setBrandId(Long brandId) {
this.brandId = brandId;
}
public Double getShippingWeight() {
return shippingWeight;
}
public void setShippingWeight(Double shippingWeight) {
this.shippingWeight = shippingWeight;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public Long getCountryId() {
return countryId;
}
public void setCountryId(Long countryId) {
this.countryId = countryId;
}
public Long getWarrantyAddress() {
return warrantyAddress;
}
public void setWarrantyAddress(Long warrantyAddress) {
this.warrantyAddress = warrantyAddress;
}
public String getWarrantyPhone() {
return warrantyPhone;
}
public void setWarrantyPhone(String warrantyPhone) {
this.warrantyPhone = warrantyPhone;
}
public Long getWarranty() {
return warranty;
}
public void setWarranty(Long warranty) {
this.warranty = warranty;
}
public String getWarrantyContent() {
return warrantyContent;
}
public void setWarrantyContent(String warrantyContent) {
this.warrantyContent = warrantyContent;
}
public Integer getFirstRemain() {
return firstRemain;
}
public void setFirstRemain(Integer firstRemain) {
this.firstRemain = firstRemain;
}
public Integer getImportType() {
return importType;
}
public void setImportType(Integer importType) {
this.importType = importType;
}
public Long getDepotId() {
return depotId;
}
public void setDepotId(Long depotId) {
this.depotId = depotId;
}
public String getSupplierName() {
return supplierName;
}
public void setSupplierName(String supplierName) {
this.supplierName = supplierName;
}
public Long getSupplierId() {
return supplierId;
}
public void setSupplierId(Long supplierId) {
this.supplierId = supplierId;
}
public Integer getCheckcopyImg() {
return checkcopyImg;
}
public void setCheckcopyImg(Integer checkcopyImg) {
this.checkcopyImg = checkcopyImg;
}
public Integer getAttributeCombinated() {
return attributeCombinated;
}
public void setAttributeCombinated(Integer attributeCombinated) {
this.attributeCombinated = attributeCombinated;
}
public String getMetaTitle() {
return metaTitle;
}
public void setMetaTitle(String metaTitle) {
this.metaTitle = metaTitle;
}
public String getMetaDescription() {
return metaDescription;
}
public void setMetaDescription(String metaDescription) {
this.metaDescription = metaDescription;
}
public Object getMetaKeywords() {
return metaKeywords;
}
public void setMetaKeywords(Object metaKeywords) {
this.metaKeywords = metaKeywords;
}
public Object getTags() {
return tags;
}
public void setTags(Object tags) {
this.tags = tags;
}
public Object getTagSuggest() {
return tagSuggest;
}
public void setTagSuggest(Object tagSuggest) {
this.tagSuggest = tagSuggest;
}
#Override
public String toString() {
return "CreateNhanhProductRequest{" +
"nuctk='" + nuctk + '\'' +
", storeId=" + storeId +
", name='" + name + '\'' +
", typeId=" + typeId +
", parentIdName='" + parentIdName + '\'' +
", parentId=" + parentId +
", code='" + code + '\'' +
", barcode='" + barcode + '\'' +
", importPrice=" + importPrice +
", vat=" + vat +
", price=" + price +
", wholesalePrice=" + wholesalePrice +
", oldPrice=" + oldPrice +
", status=" + status +
", multiUnitItems=" + multiUnitItems +
", comboItems=" + comboItems +
", categoryId=" + categoryId +
", internalCategoryId=" + internalCategoryId +
", brandId=" + brandId +
", shippingWeight=" + shippingWeight +
", unit='" + unit + '\'' +
", length=" + length +
", width=" + width +
", height=" + height +
", countryId=" + countryId +
", warrantyAddress=" + warrantyAddress +
", warrantyPhone='" + warrantyPhone + '\'' +
", warranty=" + warranty +
", warrantyContent='" + warrantyContent + '\'' +
", firstRemain=" + firstRemain +
", importType=" + importType +
", depotId=" + depotId +
", supplierName='" + supplierName + '\'' +
", supplierId=" + supplierId +
", checkcopyImg=" + checkcopyImg +
", attributeCombinated=" + attributeCombinated +
", metaTitle='" + metaTitle + '\'' +
", metaDescription='" + metaDescription + '\'' +
", metaKeywords=" + metaKeywords +
", tags=" + tags +
", tagSuggest=" + tagSuggest +
'}';
}
// private Multi imageUpload;
}
I want to Add same nuctk in every request in the body.
But request use the formData i can't convert this to object in interceptor.
My client
package com.example.demo.client;
import com.example.demo.config.NhanhPageFeignClientInterceptor;
import com.example.demo.request.CreateNhanhProductRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
#FeignClient(
value = "nhanhPage",
url = "https://nhanh.vn/product",
configuration = NhanhPageFeignClientInterceptor.class
)
public interface NhanhProductV1Client {
#PostMapping(value = "/item/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String createProduct(#RequestBody CreateNhanhProductRequest request);
}
This is my interceptor
package com.example.demo.config;
import com.example.demo.request.CreateNhanhProductRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestInterceptor;
import feign.form.FormData;
import feign.form.FormEncoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import java.io.IOException;
public class NhanhPageFeignClientInterceptor {
#Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
String bodyTemplate = requestTemplate.bodyTemplate();
byte[] body = requestTemplate.body();
FormData formData = new FormData(MediaType.MULTIPART_FORM_DATA_VALUE, "data" , body);
requestTemplate.header(HttpHeaders.COOKIE, "Some cookie");
};
}
}
How to change the body in feign client interceptor.
Thank!

Related

Spring Batch FlatFileItemWriter

salve sto cercando di leggere u oggetto e scivere un oggetto ma ricevo un errore :
Invalid property 'KDE22' of bean class [com.Bnl.Wl.Batch2.Model.EmployeeOut]: Bean property 'KDE22' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
#Bean
public FlatFileItemWriter<EmployeeOut> writer() throws IOException {
FlatFileItemWriter<EmployeeOut> writer = new FlatFileItemWriter<EmployeeOut>();
writer.setAppendAllowed(true);
System.out.println("conteggio " + conteggio);
writer.setResource(new FileSystemResource(dirOutputPath + dharControlEnvironment + nameAppOrigin
+ sdf1.format(timestamp) + String.format("%03d", conteggio + 1).toString() + ".txt"));
DelimitedLineAggregator<EmployeeOut> aggregator = new DelimitedLineAggregator<>();
BeanWrapperFieldExtractor<EmployeeOut> fieldExtractor = new BeanWrapperFieldExtractor<>();
fieldExtractor.setNames(EmployeeOut.fields());
aggregator.setFieldExtractor(fieldExtractor);
aggregator.setDelimiter("|");
System.out.println(writer.getExecutionContextKey(dharControlEnvironment).toString());
writer.setLineAggregator(aggregator);
writer.setHeaderCallback(
(org.springframework.batch.item.file.FlatFileHeaderCallback) new FlatFileHeaderCallback() {
public void writeHeader(Writer writer) throws IOException {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
writer.write("00" + "|" + sdf1.format(timestamp) + "|" + dharControlEnvironment + nameAppOrigin
+ "ANAGPILOTA");
}
});
writer.setFooterCallback(new FlatFileFooterCallback() {
#Override
public void writeFooter(Writer writer) throws IOException {
int cont = 0;
FileReader reader = new FileReader(dirOutputPath + dharControlEnvironment + nameAppOrigin
+ sdf1.format(timestamp) + String.format("%03d", conteggio + 1).toString() + extention);
BufferedReader in = new BufferedReader(reader);
while (in.readLine() != null)
cont++;
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
writer.write("99" + "|" + sdf1.format(timestamp) + "|" + dharControlEnvironment + nameAppOrigin + "|"
+ cont);
writer.write(System.lineSeparator());
}
});
return writer;
}
public class EmployeeItemProcessor implements ItemProcessor<Employee, EmployeeOut> {
private static final Logger log = LoggerFactory.getLogger(JobExecutionListener.class);
//private EmployeeOut itemOut = new EmployeeOut();
#Override
public EmployeeOut process(Employee item) throws Exception {
EmployeeOut itemOut = new EmployeeOut();
itemOut.setCOMPETENCE_DATE("afafafasdfadsfasdf");
itemOut.setDIVISA(item.getDIVISA());
itemOut.setCONTO_CONTABILE(item.getCONTO_CONTABILE());
itemOut.setTIPO_SCRITTURA(item.getID_SCRITTURA());
itemOut.setIMPORTO(item.getIMPORTO());
itemOut.setDATA_VALUTA(item.getDATA_VALUTA());
itemOut.setOM_BN(item.getOM_BN());
itemOut.setDOSSIER(item.getDOSSIER());
itemOut.setKDE1(item.getKDE1());
itemOut.setNDG(item.getNDG());
itemOut.setIBAN(item.getIBAN());
itemOut.setKDE2(item.getKDE2());
itemOut.setKDE3(item.getKDE3());
itemOut.setTIPO_EVENTO(item.getTIPO_EVENTO());
itemOut.setID_SCRITTURA(item.getID_SCRITTURA());
itemOut.setSIGLA_CIRCUITO(item.getSIGLA_CIRCUITO());
itemOut.setDATA_TESORERIA(item.getDATA_TESORERIA());
itemOut.setCOMPETENZA(item.getCOMPETENZA());
itemOut.setFLAG_SUBGROUP(item.getFLAG_SUBGROUP());
itemOut.setOPERATION(item.getOPERATION());
itemOut.setNew_field1("prova222");
itemOut.setNew_field1("prova");
itemOut.setNew_field2("sdfsdff");
log.info("filed 1 "+ itemOut.getNew_field1());
return itemOut;
}
}
package com.Bnl.Wl.Batch2.Model;
public class Employee {
protected String COMPETENCE_DATE;
protected String DIVISA;
protected String CONTO_CONTABILE;
protected String TIPO_SCRITTURA;
protected String IMPORTO;
protected String DATA_VALUTA;
protected String OM_BN;
protected String DOSSIER;
protected String KDE1;
protected String NDG;
protected String IBAN;
protected String KDE2;
protected String KDE3;
protected String TIPO_EVENTO;
protected String ID_SCRITTURA;
protected String SIGLA_CIRCUITO;
protected String DATA_TESORERIA;
protected String COMPETENZA;
protected String FLAG_SUBGROUP;
protected String OPERATION;
public Employee() {
}
public static String[] fields() {
return new String[] {"COMPETENCE_DATE",
"DIVISA",
"CONTO_CONTABILE",
"TIPO_SCRITTURA",
"IMPORTO",
"DATA_VALUTA",
"OM_BN",
"DOSSIER",
"KDE1",
"NDG",
"IBAN",
"KDE2",
"KDE3",
"TIPO_EVENTO",
"ID_SCRITTURA",
"SIGLA_CIRCUITO",
"DATA_TESORERIA",
"COMPETENZA",
"FLAG_SUBGROUP",
"OPERATION",
};
}
public String getCOMPETENCE_DATE() {
return COMPETENCE_DATE;
}
public void setCOMPETENCE_DATE(String cOMPETENCE_DATE) {
COMPETENCE_DATE = cOMPETENCE_DATE;
}
public String getDIVISA() {
return DIVISA;
}
public void setDIVISA(String dIVISA) {
DIVISA = dIVISA;
}
public String getCONTO_CONTABILE() {
return CONTO_CONTABILE;
}
public void setCONTO_CONTABILE(String cONTO_CONTABILE) {
CONTO_CONTABILE = cONTO_CONTABILE;
}
public String getTIPO_SCRITTURA() {
return TIPO_SCRITTURA;
}
public void setTIPO_SCRITTURA(String tIPO_SCRITTURA) {
TIPO_SCRITTURA = tIPO_SCRITTURA;
}
public String getIMPORTO() {
return IMPORTO;
}
public void setIMPORTO(String iMPORTO) {
IMPORTO = iMPORTO;
}
public String getDATA_VALUTA() {
return DATA_VALUTA;
}
public void setDATA_VALUTA(String dATA_VALUTA) {
DATA_VALUTA = dATA_VALUTA;
}
public String getOM_BN() {
return OM_BN;
}
public void setOM_BN(String oM_BN) {
OM_BN = oM_BN;
}
public String getDOSSIER() {
return DOSSIER;
}
public void setDOSSIER(String dOSSIER) {
DOSSIER = dOSSIER;
}
public String getKDE1() {
return KDE1;
}
public void setKDE1(String kDE1) {
KDE1 = kDE1;
}
public String getNDG() {
return NDG;
}
public void setNDG(String nDG) {
NDG = nDG;
}
public String getIBAN() {
return IBAN;
}
public void setIBAN(String iBAN) {
IBAN = iBAN;
}
public String getKDE2() {
return KDE2;
}
public void setKDE2(String kDE2) {
KDE2 = kDE2;
}
public String getKDE3() {
return KDE3;
}
public void setKDE3(String kDE3) {
KDE3 = kDE3;
}
public String getTIPO_EVENTO() {
return TIPO_EVENTO;
}
public void setTIPO_EVENTO(String tIPO_EVENTO) {
TIPO_EVENTO = tIPO_EVENTO;
}
public String getID_SCRITTURA() {
return ID_SCRITTURA;
}
public void setID_SCRITTURA(String iD_SCRITTURA) {
ID_SCRITTURA = iD_SCRITTURA;
}
public String getSIGLA_CIRCUITO() {
return SIGLA_CIRCUITO;
}
public void setSIGLA_CIRCUITO(String sIGLA_CIRCUITO) {
SIGLA_CIRCUITO = sIGLA_CIRCUITO;
}
public String getDATA_TESORERIA() {
return DATA_TESORERIA;
}
public void setDATA_TESORERIA(String dATA_TESORERIA) {
DATA_TESORERIA = dATA_TESORERIA;
}
public String getCOMPETENZA() {
return COMPETENZA;
}
public void setCOMPETENZA(String cOMPETENZA) {
COMPETENZA = cOMPETENZA;
}
public String getFLAG_SUBGROUP() {
return FLAG_SUBGROUP;
}
public void setFLAG_SUBGROUP(String fLAG_SUBGROUP) {
FLAG_SUBGROUP = fLAG_SUBGROUP;
}
public String getOPERATION() {
return OPERATION;
}
public void setOPERATION(String oPERATION) {
OPERATION = oPERATION;
}
}
package com.Bnl.Wl.Batch2.Model;
public class EmployeeOut extends Employee {
private String New_field1;
public String getNew_field1() {
return New_field1;
}
public void setNew_field1(String new_field1) {
New_field1 = new_field1;
}
public String getNew_field2() {
return New_field2;
}
public void setNew_field2(String new_field2) {
New_field2 = new_field2;
}
private String New_field2;
public EmployeeOut() {
super();
// TODO Auto-generated constructor stub
}
public static String[] fields() {
return new String[] { "COMPETENCE_DATE", "DIVISA", "CONTO_CONTABILE", "TIPO_SCRITTURA", "IMPORTO",
"DATA_VALUTA", "OM_BN", "DOSSIER", "KDE1", "NDG", "IBAN", "KDE22", "KDE3", "TIPO_EVENTO", "ID_SCRITTURA",
"SIGLA_CIRCUITO", "DATA_TESORERIA", "COMPETENZA", "FLAG_SUBGROUP", "OPERATION", "Field1", "Field2" };
}
}
object with n fields Object with n fields + m, but something goes wrong

Field value in a Class does not get updated with Spring Boot MVC Controller

I have a Parcel Entity, and I am populating the fields through #PostMapping. The value Volume should be gotten from a method taking in values from the agruments in the constructor.
Controller Class:
#Controller
public class Controller {
#Value("#{${listOfBases}}")
private List<String> listOfBases;
#Value("#{${listOfDestinations}}")
private List<String> listOfDestinations;
#Autowired
ParcelRepository parcelRepository;
#GetMapping("/register_parcel")
public String showParcelRegistrationForm(Model model) {
Parcel parcel = new Parcel();
model.addAttribute("parcel", parcel);
model.addAttribute("listOfBases", listOfBases);
model.addAttribute("listOfDestinations", listOfDestinations);
return "parcel/register_form_parcel";
}
#PostMapping("register_parcel")
public String registerParcel(#ModelAttribute("parcel") Parcel parcel) {
System.out.println(parcel);
parcelRepository.save(parcel);
return "user/user_registration_success_form";
}
}
Parcel Class:
#Entity
public class Parcel {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
String length;
String width;
String height;
String weight;
String base;
String destination;
String creationDate;
String volume;
No args constructor:
public Parcel() {
creationDate = getCreationDateAndTime();
}
public Parcel(int id, String length, String width, String height, String weight, String base, String destination) {
this.id = id;
this.length = length;
this.width = width;
this.height = height;
this.weight = weight;
this.base = base;
this.destination = destination;
creationDate = getCreationDateAndTime();
volume = String.valueOf(calculateVolume(width, height, length));
}
Getters and Setters:
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public String getHeight() {
return height;
}
public void setHeight(String height) {
this.height = height;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getCreationDate() {
return creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public String getVolume() {
return volume;
}
public void setVolume(String volume) {
this.volume = volume;
}
private String getCreationDateAndTime() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
return dtf.format(now);
}
CalculateVolume method that is the root of the problem:
private int calculateVolume(String width, String height, String length) {
int w = Integer.parseInt(width);
int h = Integer.parseInt(height);
int l = Integer.parseInt(length);
return w * h * l;
}
But the value volume is null in my database. Even System.out.println(); in calculateVolume does not print anything on the console, but when I run create an instance in main, all runs fine and dandy.
Any ideas on how I should proceed, or is my question too vague?
Thank you
#Override
public String toString() {
return "Parcel{" +
"id=" + id +
", length='" + length + '\'' +
", width='" + width + '\'' +
", height='" + height + '\'' +
", weight='" + weight + '\'' +
", base='" + base + '\'' +
", destination='" + destination + '\'' +
", creationDate='" + creationDate + '\'' +
", volume='" + volume + '\'' +
'}';
}
}
Change Post method in your controller
from
public String registerParcel(#ModelAttribute("parcel") Parcel parcel)
to
public String registerParcel(#RequestBody Parcel parcel)

Spring BeanUtils.copyProperties not working

I want to copy properties from one object to another, both are of the same class. However it's not copying the fields. Here is the demo code:
public static void main(String[] args) throws Exception {
A from = new A();
A to = new A();
from.i = 123;
from.l = 321L;
System.out.println(from.toString());
System.out.println(to.toString());
BeanUtils.copyProperties(from, to);
System.out.println(from.toString());
System.out.println(to.toString());
}
public static class A {
public String s;
public Integer i;
public Long l;
#Override
public String toString() {
return "A{" +
"s=" + s +
", i=" + i +
", l=" + l +
'}';
}
}
And the output is:
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
Looks like I have to have setter/getters for the class:
public static void main(String[] args) throws Exception {
A from = new A();
A to = new A();
from.i = 123;
from.l = 321L;
System.out.println(from.toString());
System.out.println(to.toString());
BeanUtils.copyProperties(from, to);
System.out.println(from.toString());
System.out.println(to.toString());
}
public static class A {
public String s;
public Integer i;
public Long l;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public Long getL() {
return l;
}
public void setL(Long l) {
this.l = l;
}
#Override
public String toString() {
return "A{" +
"s=" + s +
", i=" + i +
", l=" + l +
'}';
}
}
Now the output is:
A{s=null, i=123, l=321}
A{s=null, i=null, l=null}
A{s=null, i=123, l=321}
A{s=null, i=123, l=321}

spring-data-jpa insert an entire entity

I'm new to spring-data-jpa and I've been doing just fine with reading records out of a database but now I would like to insert records. I would like to follow my same pattern of using the repository class along with a query to do the insertion. Is there a way similar to this post https://stackoverflow.com/a/24848086/3299397 where I can insert a record but instead of explicitly specifying each value I simply pass to the function an entity object and insert the entire object? Here is what I have so far.
Entity Class:
package blah.blah.blah;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name = "MESSAGE")
public class Message implements Serializable {
#Id
// #GeneratedValue(generator = "system-uuid")
// #GenericGenerator(name = "system-uuid", strategy = "uuid")
#Column(name = "MESSAGE_GUID")
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
private String messageGuid;
#Column(name = "MESSAGE_TYPE_CD")
private Long messageTypeCd;
#Column(name = "SENDER_GUID")
private String SenderGuid;
#Column(name = "MESSAGE_TITLE")
private String messageTitle;
#Column(name = "MESSAGE_STATUS_CD")
private Long messageStatusCd;
#Column(name = "ACTIVATED_DT")
private Date activatedDt;
#Column(name = "DEACTIVATED_DT")
private Date deactivatedDt;
#Column(name = "CREATE_BY")
private String createBy;
#Column(name = "CREATE_DT")
private Date createDt;
#Column(name = "UPDATE_BY")
private String updateBy;
#Column(name = "UPDATE_DT")
private Date updateDt;
// required by JPA
public Message() {
}
#SuppressWarnings("all")
public Message(
String messageGuid,
Long messageTypeCd,
String SenderGuid,
String messageTitle,
Long messageStatusCd,
Date activatedDt,
Date deactivatedDt,
String createBy,
Date createDt,
String updateBy,
Date updateDt) {
super();
this.messageGuid = messageGuid;
this.messageTypeCd = messageTypeCd;
this.SenderGuid = SenderGuid;
this.messageTitle = messageTitle;
this.messageStatusCd = messageStatusCd;
this.activatedDt = activatedDt;
this.deactivatedDt = deactivatedDt;
this.createBy = createBy;
this.createDt = createDt;
this.updateBy = updateBy;
this.updateDt = updateDt;
}
public String getMessageGuid() {
return messageGuid;
}
public void setMessageGuid(String messageGuid) {
this.messageGuid = messageGuid;
}
public Long getMessageTypeCd() {
return messageTypeCd;
}
public void setMessageTypeCd(Long messageTypeCd) {
this.messageTypeCd = messageTypeCd;
}
public String getSenderGuid() {
return SenderGuid;
}
public void setSenderGuid(String senderGuid) {
SenderGuid = senderGuid;
}
public String getMessageTitle() {
return messageTitle;
}
public void setMessageTitle(String messageTitle) {
this.messageTitle = messageTitle;
}
public Long getMessageStatusCd() {
return messageStatusCd;
}
public void setMessageStatusCd(Long messageStatusCd) {
this.messageStatusCd = messageStatusCd;
}
public Date getActivatedDt() {
return activatedDt;
}
public void setActivatedDt(Date activatedDt) {
this.activatedDt = activatedDt;
}
public Date getDeactivatedDt() {
return deactivatedDt;
}
public void setDeactivatedDt(Date deactivatedDt) {
this.deactivatedDt = deactivatedDt;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateDt() {
return createDt;
}
public void setCreateDt(Date createDt) {
this.createDt = createDt;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateDt() {
return updateDt;
}
public void setUpdateDt(Date updateDt) {
this.updateDt = updateDt;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((SenderGuid == null) ? 0 : SenderGuid.hashCode());
result = prime * result + ((activatedDt == null) ? 0 : activatedDt.hashCode());
result = prime * result + ((createBy == null) ? 0 : createBy.hashCode());
result = prime * result + ((createDt == null) ? 0 : createDt.hashCode());
result = prime * result + ((deactivatedDt == null) ? 0 : deactivatedDt.hashCode());
result = prime * result + ((messageGuid == null) ? 0 : messageGuid.hashCode());
result = prime * result + ((messageStatusCd == null) ? 0 : messageStatusCd.hashCode());
result = prime * result + ((messageTitle == null) ? 0 : messageTitle.hashCode());
result = prime * result + ((messageTypeCd == null) ? 0 : messageTypeCd.hashCode());
result = prime * result + ((updateBy == null) ? 0 : updateBy.hashCode());
result = prime * result + ((updateDt == null) ? 0 : updateDt.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Message other = (Message) obj;
if (SenderGuid == null) {
if (other.SenderGuid != null)
return false;
} else if (!SenderGuid.equals(other.SenderGuid))
return false;
if (activatedDt == null) {
if (other.activatedDt != null)
return false;
} else if (!activatedDt.equals(other.activatedDt))
return false;
if (createBy == null) {
if (other.createBy != null)
return false;
} else if (!createBy.equals(other.createBy))
return false;
if (createDt == null) {
if (other.createDt != null)
return false;
} else if (!createDt.equals(other.createDt))
return false;
if (deactivatedDt == null) {
if (other.deactivatedDt != null)
return false;
} else if (!deactivatedDt.equals(other.deactivatedDt))
return false;
if (messageGuid == null) {
if (other.messageGuid != null)
return false;
} else if (!messageGuid.equals(other.messageGuid))
return false;
if (messageStatusCd == null) {
if (other.messageStatusCd != null)
return false;
} else if (!messageStatusCd.equals(other.messageStatusCd))
return false;
if (messageTitle == null) {
if (other.messageTitle != null)
return false;
} else if (!messageTitle.equals(other.messageTitle))
return false;
if (messageTypeCd == null) {
if (other.messageTypeCd != null)
return false;
} else if (!messageTypeCd.equals(other.messageTypeCd))
return false;
if (updateBy == null) {
if (other.updateBy != null)
return false;
} else if (!updateBy.equals(other.updateBy))
return false;
if (updateDt == null) {
if (other.updateDt != null)
return false;
} else if (!updateDt.equals(other.updateDt))
return false;
return true;
}
#Override
public String toString() {
return "Message [messageGuid=" + messageGuid + ", messageTypeCd=" + messageTypeCd + ", SenderGuid="
+ SenderGuid + ", messageTitle=" + messageTitle + ", messageStatusCd=" + messageStatusCd
+ ", activatedDt=" + activatedDt + ", deactivatedDt=" + deactivatedDt + ", createBy=" + createBy
+ ", createDt=" + createDt + ", updateBy=" + updateBy + ", updateDt=" + updateDt + "]";
}
}
Repository Class:
package blah.blah.blah;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
#Repository
public interface MessageRepository extends JpaRepository<Message, String> {
#Query("SELECT "
+ "m "
+ "FROM Message m "
+ "WHERE messageGuid = :messageGuid")
List<Message> findByMessageGuid(#Param("messageGuid") String messageGuid);
// THIS DOES NOT WORK!
// #Query("INSERT "
// + "INTO Message")
// void insertMessage(#Param("myMessage") Message myMessage);
}
Service Class:
package blah.blah.blah;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class MessageServiceImpl implements MessageService {
private static final Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);
#Autowired
private MessageRepository messageRepository;
#Override
public void getMessage(String messageGuid) {
List<Message> messageList = messageRepository.findByMessageGuid(messageGuid);
for (Message message : messageList)
log.info("\n\n" + message.toString() + "\n\n");
}
Component Class:
#Component
public class MessageComponentThingy {
#Autowired
MessageService messageService;
public void thisIsALongExample() {
messageService.getMessage("34A02DCF520F0831E053870910ACED7A");
}
}
This works for me when I want to read a record from the database...
Update Note: Please note that I am not necessarily concerned with doing 'Native Queries' I would just like to keep the same general pattern as what is shown in my Repository class. I would not reject an answer that uses a Native Query though. It honestly doesn't matter to me.
I didn't realize how simple this was. I am already inheriting the JpaRepository inside my repository class. JpaRepository has a method called 'save'. So you simply call that method. Everything works now....
I added new code below to the Service class (there's a new put method for the insert) and to the Component class (you can see me call the service classes put method). Hope this helps someone in the future.
Entity Class:
package blah.blah.blah;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
#Entity
#Table(name = "MESSAGE")
public class Message implements Serializable {
#Id
// #GeneratedValue(generator = "system-uuid")
// #GenericGenerator(name = "system-uuid", strategy = "uuid")
#Column(name = "MESSAGE_GUID")
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid")
private String messageGuid;
#Column(name = "MESSAGE_TYPE_CD")
private Long messageTypeCd;
#Column(name = "SENDER_GUID")
private String SenderGuid;
#Column(name = "MESSAGE_TITLE")
private String messageTitle;
#Column(name = "MESSAGE_STATUS_CD")
private Long messageStatusCd;
#Column(name = "ACTIVATED_DT")
private Date activatedDt;
#Column(name = "DEACTIVATED_DT")
private Date deactivatedDt;
#Column(name = "CREATE_BY")
private String createBy;
#Column(name = "CREATE_DT")
private Date createDt;
#Column(name = "UPDATE_BY")
private String updateBy;
#Column(name = "UPDATE_DT")
private Date updateDt;
// required by JPA
public Message() {
}
#SuppressWarnings("all")
public Message(
String messageGuid,
Long messageTypeCd,
String SenderGuid,
String messageTitle,
Long messageStatusCd,
Date activatedDt,
Date deactivatedDt,
String createBy,
Date createDt,
String updateBy,
Date updateDt) {
super();
this.messageGuid = messageGuid;
this.messageTypeCd = messageTypeCd;
this.SenderGuid = SenderGuid;
this.messageTitle = messageTitle;
this.messageStatusCd = messageStatusCd;
this.activatedDt = activatedDt;
this.deactivatedDt = deactivatedDt;
this.createBy = createBy;
this.createDt = createDt;
this.updateBy = updateBy;
this.updateDt = updateDt;
}
public String getMessageGuid() {
return messageGuid;
}
public void setMessageGuid(String messageGuid) {
this.messageGuid = messageGuid;
}
public Long getMessageTypeCd() {
return messageTypeCd;
}
public void setMessageTypeCd(Long messageTypeCd) {
this.messageTypeCd = messageTypeCd;
}
public String getSenderGuid() {
return SenderGuid;
}
public void setSenderGuid(String senderGuid) {
SenderGuid = senderGuid;
}
public String getMessageTitle() {
return messageTitle;
}
public void setMessageTitle(String messageTitle) {
this.messageTitle = messageTitle;
}
public Long getMessageStatusCd() {
return messageStatusCd;
}
public void setMessageStatusCd(Long messageStatusCd) {
this.messageStatusCd = messageStatusCd;
}
public Date getActivatedDt() {
return activatedDt;
}
public void setActivatedDt(Date activatedDt) {
this.activatedDt = activatedDt;
}
public Date getDeactivatedDt() {
return deactivatedDt;
}
public void setDeactivatedDt(Date deactivatedDt) {
this.deactivatedDt = deactivatedDt;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public Date getCreateDt() {
return createDt;
}
public void setCreateDt(Date createDt) {
this.createDt = createDt;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public Date getUpdateDt() {
return updateDt;
}
public void setUpdateDt(Date updateDt) {
this.updateDt = updateDt;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((SenderGuid == null) ? 0 : SenderGuid.hashCode());
result = prime * result + ((activatedDt == null) ? 0 : activatedDt.hashCode());
result = prime * result + ((createBy == null) ? 0 : createBy.hashCode());
result = prime * result + ((createDt == null) ? 0 : createDt.hashCode());
result = prime * result + ((deactivatedDt == null) ? 0 : deactivatedDt.hashCode());
result = prime * result + ((messageGuid == null) ? 0 : messageGuid.hashCode());
result = prime * result + ((messageStatusCd == null) ? 0 : messageStatusCd.hashCode());
result = prime * result + ((messageTitle == null) ? 0 : messageTitle.hashCode());
result = prime * result + ((messageTypeCd == null) ? 0 : messageTypeCd.hashCode());
result = prime * result + ((updateBy == null) ? 0 : updateBy.hashCode());
result = prime * result + ((updateDt == null) ? 0 : updateDt.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Message other = (Message) obj;
if (SenderGuid == null) {
if (other.SenderGuid != null)
return false;
} else if (!SenderGuid.equals(other.SenderGuid))
return false;
if (activatedDt == null) {
if (other.activatedDt != null)
return false;
} else if (!activatedDt.equals(other.activatedDt))
return false;
if (createBy == null) {
if (other.createBy != null)
return false;
} else if (!createBy.equals(other.createBy))
return false;
if (createDt == null) {
if (other.createDt != null)
return false;
} else if (!createDt.equals(other.createDt))
return false;
if (deactivatedDt == null) {
if (other.deactivatedDt != null)
return false;
} else if (!deactivatedDt.equals(other.deactivatedDt))
return false;
if (messageGuid == null) {
if (other.messageGuid != null)
return false;
} else if (!messageGuid.equals(other.messageGuid))
return false;
if (messageStatusCd == null) {
if (other.messageStatusCd != null)
return false;
} else if (!messageStatusCd.equals(other.messageStatusCd))
return false;
if (messageTitle == null) {
if (other.messageTitle != null)
return false;
} else if (!messageTitle.equals(other.messageTitle))
return false;
if (messageTypeCd == null) {
if (other.messageTypeCd != null)
return false;
} else if (!messageTypeCd.equals(other.messageTypeCd))
return false;
if (updateBy == null) {
if (other.updateBy != null)
return false;
} else if (!updateBy.equals(other.updateBy))
return false;
if (updateDt == null) {
if (other.updateDt != null)
return false;
} else if (!updateDt.equals(other.updateDt))
return false;
return true;
}
#Override
public String toString() {
return "Message [messageGuid=" + messageGuid + ", messageTypeCd=" + messageTypeCd + ", SenderGuid="
+ SenderGuid + ", messageTitle=" + messageTitle + ", messageStatusCd=" + messageStatusCd
+ ", activatedDt=" + activatedDt + ", deactivatedDt=" + deactivatedDt + ", createBy=" + createBy
+ ", createDt=" + createDt + ", updateBy=" + updateBy + ", updateDt=" + updateDt + "]";
}
}
Repository Class:
package blah.blah.blah;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
#Repository
public interface MessageRepository extends JpaRepository<Message, String> {
#Query("SELECT "
+ "m "
+ "FROM Message m "
+ "WHERE messageGuid = :messageGuid")
List<Message> findByMessageGuid(#Param("messageGuid") String messageGuid);
}
Service Class:
package blah.blah.blah;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class MessageServiceImpl implements MessageService {
private static final Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);
#Autowired
private MessageRepository messageRepository;
#Override
public void getMessage(String messageGuid) {
List<Message> messageList = messageRepository.findByMessageGuid(messageGuid);
for (Message message : messageList)
log.info("\n\n" + message.toString() + "\n\n");
}
public void putMessage(Message message) {
messageRepository.save(message);
System.out.println("\n\nInside putMessage\n\n");
}
}
Component Class:
#Component
public class MessageComponentThingy {
#Autowired
MessageService messageService;
public void thisIsALongExample() {
messageService.getMessage("34A02DCF520F0831E053870910ACED7A");
Message message = new Message();
message.setMessageTypeCd(1L);
message.setSenderGuid("test");
message.setMessageTitle("test title");
message.setMessageStatusCd(1L);
message.setActivatedDt(new Date());
message.setDeactivatedDt(new Date());
message.setCreateBy("me");
message.setCreateDt(new Date());
message.setUpdateBy("me");
message.setUpdateDt(new Date());
messageService.putMessage(message);
}
}

Neo4j: Special characters and time lag

Goal: I am trying to make a Neo4j instance of the DBLP database on the basis of the publicly available DBLP XML file available here. I have modeled the database as a bipartite graph where the authors are in one set and the publications in the other set. To obtain all coauthors of John Doe one has to make the following Cypher query:
MATCH (a:Author)-[:WROTE]->(publication)<-[:WROTE]-(b:Author) WHERE a.name = "John Doe" RETURN DISTINCT b"
Problem 1: There seems to be a problem partly related to special characters, such as ë, æ, í, etc. When I, in my browser at the address http://localhost:7474/browser/, enter the query "MATCH (a:Author)-[:WROTE]->(p)<-[:WROTE]-(b:Author) WHERE a.name = "Jan Arne Telle" RETURN DISTINCT b", I should get 58 unique results (coauthors), but I get 79 results. For instance, coauthor Daniël Paulusma is split into three results: "Dani", "ë", "l Paulusma". But in fact, I also get coauthor David Keldsen as three results: "David Keldsen", "David", and "Keldsen". So the problem is not only related to special characters.
Problem 2: Results for the above mentioned query were returned in 90697 ms.
EDIT: After making several such queries results are returned in 2000 ms to 4000 ms.
Here is all the code:
Entry point: Application.java:
package std;
import java.io.File;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.kernel.impl.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.core.GraphDatabase;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.apache.xerces.util.SecurityManager;
#SpringBootApplication
public class Application implements CommandLineRunner {
#Configuration
#EnableNeo4jRepositories(basePackages = "std")
static class ApplicationConfig extends Neo4jConfiguration {
public ApplicationConfig() {
setBasePackage("std");
}
#Bean
GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("dblp.db");
}
}
#Autowired
PublicationRepository publicationRepository;
#Autowired
GraphDatabase graphDatabase;
public void run(String... args) throws Exception {
Transaction tx = graphDatabase.beginTx();
try {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser parser = parserFactory.newSAXParser();
SecurityManager mgr = new SecurityManager();
mgr.setEntityExpansionLimit(3100000);
parser.setProperty("http://apache.org/xml/properties/security-manager", mgr);
SaxHandler handler = new SaxHandler(publicationRepository, graphDatabase);
handler.setTransaction(tx);
parser.getXMLReader().setFeature("http://xml.org/sax/features/validation", true);
InputStream xmlInput = new FileInputStream("/Users/username/Documents/dblp.xml");
parser.parse(xmlInput, handler);
tx.success();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} finally {
tx.close();
}
}
public static void main(String[] args) throws Exception {
FileUtils.deleteRecursively(new File("dblp.db"));
SpringApplication.run(Application.class, args);
}
}
Author.java:
package std;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.support.index.IndexType;
#NodeEntity
public class Author {
#GraphId
private Long id;
#Indexed(indexName = "names", unique = true, indexType = IndexType.FULLTEXT)
private String name;
public Author() {
}
public Author(String name) {
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
Author other = (Author) obj;
if (this.id != null && this.name != null && other.id != null && other.name != null) {
if (this.id.equals(other.id) && this.name.equals(other.name))
return true;
} else {
return true;
}
return false;
}
#Override
public int hashCode() {
return 31 * (this.id == null ? 1 : this.id.hashCode()) + 31 * (this.name == null ? 1 : this.name.hashCode());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Publication.java:
package std;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.support.index.IndexType;
#NodeEntity
public class Publication implements Serializable {
private static final long serialVersionUID = -6393545300391560520L;
#GraphId
Long nodeId;
private String type = "";
private String key = "";
private String mdate = "";
private String publtype = "";
private String reviewid = "";
private String rating = "";
#RelatedTo(type = "WROTE", direction = Direction.INCOMING)
private Set<Author> authors = new HashSet<Author>();
private String editor = "";
#Indexed(indexType = IndexType.FULLTEXT, indexName = "titles")
private String title = "";
private String booktitle = "";
private String pages = "";
private String year = "";
private String address = "";
private String journal = "";
private String volume = "";
private String number = "";
private String month = "";
private String url = "";
private String ee = "";
private String cdrom = "";
private String cite = "";
private String publisher = "";
private String note = "";
private String crossref = "";
private String isbn = "";
private String series = "";
private String school = "";
private String chapter = "";
public Publication() {
}
public void addAuthor(Author author) {
authors.add(author);
}
public Set<Author> getAuthors() {
return authors;
}
public void setAuthors(Set<Author> authors) {
this.authors = authors;
}
#Override
public String toString() {
return "TYPE: " + type + "\n"
+ "KEY: " + key + "\n"
+ "MDATE: " + mdate + "\n";
}
public Long getNodeId() {
return nodeId;
}
public void setNodeId(Long nodeId) {
this.nodeId = nodeId;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getMdate() {
return mdate;
}
public void setMdate(String mdate) {
this.mdate = mdate;
}
public String getPubltype() {
return publtype;
}
public void setPubltype(String publtype) {
this.publtype = publtype;
}
public String getReviewid() {
return reviewid;
}
public void setReviewid(String reviewid) {
this.reviewid = reviewid;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEditor() {
return editor;
}
public void setEditor(String editor) {
this.editor = editor;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBooktitle() {
return booktitle;
}
public void setBooktitle(String booktitle) {
this.booktitle = booktitle;
}
public String getPages() {
return pages;
}
public void setPages(String pages) {
this.pages = pages;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getJournal() {
return journal;
}
public void setJournal(String journal) {
this.journal = journal;
}
public String getVolume() {
return volume;
}
public void setVolume(String volume) {
this.volume = volume;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getEe() {
return ee;
}
public void setEe(String ee) {
this.ee = ee;
}
public String getCdrom() {
return cdrom;
}
public void setCdrom(String cdrom) {
this.cdrom = cdrom;
}
public String getCite() {
return cite;
}
public void setCite(String cite) {
this.cite = cite;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getCrossref() {
return crossref;
}
public void setCrossref(String crossref) {
this.crossref = crossref;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getSeries() {
return series;
}
public void setSeries(String series) {
this.series = series;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getChapter() {
return chapter;
}
public void setChapter(String chapter) {
this.chapter = chapter;
}
}
PublicationRepository.java:
package std;
import org.springframework.data.neo4j.repository.GraphRepository;
public interface PublicationRepository extends GraphRepository<Publication> {
Publication findByTitle(String title);
}
SaxHandler.java:
package std;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.neo4j.graphdb.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.neo4j.core.GraphDatabase;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SaxHandler extends DefaultHandler {
private Stack<String> qNameStack = new Stack<String>();
private Stack<Publication> publicationStack = new Stack<Publication>();
private String publicationType = null;
private PublicationRepository publicationRepository = null;
private Publication publication = null;
private Author author = null;
private String currentElement = null;
private String value = null;
private boolean insideTitle = false;
private GraphDatabase graphDatabase;
private Transaction tx = null;
private static int counter = 0;
public List<Publication> getPublications() {
return publications;
}
#Autowired
public SaxHandler(PublicationRepository publicationRepository, GraphDatabase graphDatabase) {
this.publicationRepository = publicationRepository;
this.graphDatabase = graphDatabase;
}
public void setTransaction(Transaction tx) {
this.tx = tx;
}
public void startElement(String uri, String localName, String tagName, Attributes attributes) throws SAXException {
storeTagName(tagName);
createEmptyPublication();
testIfEnteringTitle(tagName);
testIfPublicationTag(tagName);
testOnAttributes(tagName, attributes);
}
public void endElement(String uri, String localName, String tagName) throws SAXException {
testIfLeavingTitle(tagName);
removeNameOfLastVisitedTag();
testIfFinishedCreatingPublication(tagName);
}
public void characters(char ch[], int start, int length) throws SAXException {
storeContentsInCurrentPublication(ch, start, length);
}
/**
* Store the contents of the current tag in the corresponding field
* of the current publication.
*
* #param ch
* #param start
* #param length
*/
private void storeContentsInCurrentPublication(char ch[], int start, int length) {
value = new String(ch,start,length).trim();
if (value.length() == 0)
return;
publication = publicationStack.peek();
currentElement = qNameStack.peek();
if ("author".equals(currentElement)) {
author = new Author();
author.setName(value);
publication.addAuthor(author);
} else if ("editor".equals(currentElement)) {
publication.setEditor(value);
} else if ("title".equals(currentElement)) {
String title = publication.getTitle() + value;
publication.setTitle(title);
} else if ("booktitle".equals(currentElement)) {
publication.setBooktitle(value);
} else if ("pages".equals(currentElement)) {
publication.setPages(value);
} else if ("year".equals(currentElement)) {
publication.setYear(value);
} else if ("address".equals(currentElement)) {
publication.setAddress(value);
} else if ("journal".equals(currentElement)) {
publication.setJournal(value);
} else if ("volume".equals(currentElement)) {
publication.setVolume(value);
} else if ("number".equals(currentElement)) {
publication.setNumber(value);
} else if ("month".equals(currentElement)) {
publication.setMonth(value);
} else if ("url".equals(currentElement)) {
publication.setUrl(value);
} else if ("ee".equals(currentElement)) {
publication.setEe(value);
} else if ("cdrom".equals(currentElement)) {
publication.setCdrom(value);
} else if ("cite".equals(currentElement)) {
publication.setCite(value);
} else if ("publisher".equals(currentElement)) {
publication.setPublisher(value);
} else if ("note".equals(currentElement)) {
publication.setNote(value);
} else if ("crossref".equals(currentElement)) {
publication.setCrossref(value);
} else if ("isbn".equals(currentElement)) {
publication.setIsbn(value);
} else if ("series".equals(currentElement)) {
publication.setSeries(value);
} else if ("school".equals(currentElement)) {
publication.setSchool(value);
} else if ("chapter".equals(currentElement)) {
publication.setChapter(value);
} else if ("i".equals(currentElement) && isInsideTitleOrBooktitle()) {
String title = publication.getTitle() + "<i>" + value + "</i>";
publication.setTitle(title);
} else if ("sup".equals(currentElement) && isInsideTitleOrBooktitle()) {
String title = publication.getTitle() + "<sup>" + value + "</sup>";
publication.setTitle(title);
} else if ("sub".equals(currentElement) && isInsideTitleOrBooktitle()) {
String title = publication.getTitle() + "<sub>" + value + "</sub>";
publication.setTitle(title);
} else if ("tt".equals(currentElement) && isInsideTitleOrBooktitle()) {
String title = publication.getTitle() + "<tt>" + value + "</tt>";
publication.setTitle(title);
} else if ("ref".equals(currentElement) && isInsideTitleOrBooktitle()) {
String title = publication.getTitle() + "<ref>" + value + "</ref>";
publication.setTitle(title);
}
}
/**
* Returns true if and only if the parser is inside
* either a title or booktitle tag.
*
* #return true if and only if the parser is inside
* either a title or booktitle tag.
*/
private boolean isInsideTitleOrBooktitle() {
return insideTitle;
}
/**
* Checks if the parser is finished with one whole
* publication. If so, the publication is stored in
* the database.
*
* #param tagName
*/
private void testIfFinishedCreatingPublication(String tagName) {
if (publicationType.equals(tagName)) {
publicationRepository.save(publicationStack.pop());
if (++counter % 1000 == 0) {
System.out.println("Counter = " + counter);
tx.success();
tx.close();
tx = graphDatabase.beginTx();
}
}
}
/**
* Removes the tag name of the last visited tag
* from the stack.
*/
private void removeNameOfLastVisitedTag() {
qNameStack.pop();
}
/**
* Store the tag name on the stack.
*
* #param tagName
*/
private void storeTagName(String tagName) {
qNameStack.push(tagName);
}
/**
* Create an empty publication to be filled with data.
*/
private void createEmptyPublication() {
publication = new Publication();
}
/**
* Checks if the parser is entering a title or booktitle tag. If so
* is the case, then a boolean flag is set.
*
* #param tagName the name of the current tag
*/
private void testIfLeavingTitle(String tagName) {
if ("title".equals(tagName) || "booktitle".equals(tagName))
insideTitle = false;
}
/**
* Checks if the parser is entering a title or booktitle tag. If so
* is the case, then a boolean flag is set.
*
* #param tagName the name of the current tag
*/
private void testIfEnteringTitle(String tagName) {
if ("title".equals(tagName) || "booktitle".equals(tagName))
insideTitle = true;
}
/**
* Checks if the current tag is one of:
* - article, inproceedings, proceedings, book, incollection, phdthesis, mastersthesis, www
* If the current tag is one of these, then the type of the current publication is set
* to the corresponding value.
*
* #param tagName the name of the current tag.
*/
private void testIfPublicationTag(String tagName) {
if ("article".equals(tagName)) {
publication.setType("article");
} else if ("inproceedings".equals(tagName)) {
publication.setType("inproceedings");
} else if ("proceedings".equals(tagName)) {
publication.setType("proceedings");
} else if ("book".equals(tagName)) {
publication.setType("book");
} else if ("incollection".equals(tagName)) {
publication.setType("incollection");
} else if ("phdthesis".equals(tagName)) {
publication.setType("phdthesis");
} else if ("mastersthesis".equals(tagName)) {
publication.setType("mastersthesis");
} else if ("www".equals(tagName)) {
publication.setType("www");
}
}
/**
* Checks if the tag has any attributes. If so, the existing attribute
* values are stored.
*
* A tag with attributes is one of:
* - article, inproceedings, proceedings, book, incollection, phdthesis, mastersthesis, www
*
* #param tagName the name of the current tag
* #param attributes the attributes of the current tag, if any
*/
private void testOnAttributes(String tagName, Attributes attributes) {
if (attributes.getLength() > 0) {
publicationType = tagName;
if (attributes.getValue("key") != null) {
publication.setKey(attributes.getValue("key"));
}
if (attributes.getValue("mdate") != null) {
publication.setMdate(attributes.getValue("mdate"));
}
if (attributes.getValue("publtype") != null) {
publication.setMdate(attributes.getValue("publtype"));
}
if (attributes.getValue("reviewid") != null) {
publication.setMdate(attributes.getValue("reviewid"));
}
if (attributes.getValue("rating") != null) {
publication.setMdate(attributes.getValue("rating"));
}
publicationStack.push(publication);
}
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dblp</groupId>
<artifactId>graphdbcreator</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>neo4j</id>
<name>Neo4j</name>
<url>http://m2.neo4j.org/</url>
</repository>
</repositories>
</project>
For problem 1 try to setup a manual index with an analyzer fitting your needs. See http://blog.armbruster-it.de/2014/10/deep-dive-on-fulltext-indexing-with-neo4j/ for details on how to use custom analyzers.
Another option would be to use stemming logic on application side and store the stemmed name in a secondary property.
A third option is adding "SIMILAR" relationships between author nodes referring to the very same person.
Regarding problem 2: make sure to have an index on the name property for authors:
CREATE INDEX ON :Author(name)
The difference on query times for subsequent calls is easily explained with caching, read more on http://neo4j.com/docs/stable/configuration-caches.html
It seems my SAX handler was flawed. For instance, given a tag <author>Daniël Paulusma</author>, the parser would make one call to the characters() method for "Dani", another call to characters() for "ë", and a third call to characters() for "l Paulusma". I found a simple solution to this problem here: SAX parsing and special characters.

Resources