mongoTemplate is null. Cannot understand why - mongodb

I'm trying to parse xml file and save some info in mongodb. I get the file to parse and give it to my #Controller. Here is the code of the POST method of #Controller:
#RequestMapping(value = TracksGeopointsRoutes.TRACKS, method = RequestMethod.POST)
public String tracks(#RequestParam MultipartFile file){
TracksGeopointsDoc tracksGeopointsDoc = new TracksGeopointsDoc();
try {
tracksGeopointsDoc.setFile(tracksGeopointsService.convert(file));
} catch (IOException e) {
e.printStackTrace();
}
mongoTemplate.save(tracksGeopointsDoc);
new MySaxParser(tracksGeopointsDoc.getFile().getAbsolutePath()); // here I give my file to my parser
return "com.ub.geopoints_test.index";
}
And my parser:
#Component
public class MySaxParser extends DefaultHandler{
#Autowired
MongoTemplate mongoTemplate;
private List<DotGeopointsDoc> dotGeopointsDocList;
String xmlFileName;
private String tmpValue;
private DotGeopointsDoc currentDotGeopointsDoc;
private DotGeopointsDoc dotGeopointsDoc;
String bookXmlFileName;
public MySaxParser() {
}
public MySaxParser(String bookXmlFileName) {
this.xmlFileName = bookXmlFileName;
dotGeopointsDocList = new ArrayList<DotGeopointsDoc>();
dotGeopointsDoc = new DotGeopointsDoc();
parseDocument();
}
private void parseDocument() {
// parse
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(xmlFileName, this);
} catch (ParserConfigurationException e) {
System.out.println("ParserConfig error");
} catch (SAXException e) {
System.out.println("SAXException : xml not well formed");
} catch (IOException e) {
System.out.println("IO error");
}
}
#Override
public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
if (elementName.equalsIgnoreCase("trkpt")) {
dotGeopointsDoc.setId(new ObjectId());
dotGeopointsDoc.setLat(attributes.getValue("lat"));
dotGeopointsDoc.setLon(attributes.getValue("lon"));
}
}
#Override
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equals("trkpt")) {
dotGeopointsDocList.add(dotGeopointsDoc);
mongoTemplate.save(dotGeopointsDoc); // here I'm getting NullPointerException. My mongoTemplate is null
dotGeopointsDoc = new DotGeopointsDoc();
}
}
#Override
public void characters(char[] ac, int i, int j) throws SAXException {
tmpValue = new String(ac, i, j);
}
}
Really don't understand why my mongoTemplate is null. Cause in my #Controller it is not. Could anyone help me?

Its because Spring doesn't know about your MySaxParser. You should not instentiate by it your self, what you did here in your controller:
new MySaxParser(tracksGeopointsDoc.getFile().getAbsolutePath());
This is how your controller should look like:
#Autowired
private MySaxParser mySaxParser;//this is how you can inject a spring managed object
#RequestMapping(value = TracksGeopointsRoutes.TRACKS, method = RequestMethod.POST)
public String tracks(#RequestParam MultipartFile file) {
TracksGeopointsDoc tracksGeopointsDoc = new TracksGeopointsDoc();
try {
tracksGeopointsDoc.setFile(tracksGeopointsService.convert(file));
} catch (IOException e) {
e.printStackTrace();
}
mongoTemplate.save(tracksGeopointsDoc);
mySaxParser.setUpMySaxParser(tracksGeopointsDoc.getFile().getAbsolutePath());
return "com.ub.geopoints_test.index";
}
and this is how your xml parser should be changed:
#Service//this is more of a service then a component
public class MySaxParser extends DefaultHandler {
#Autowired
private MongoTemplate mongoTemplate;
private List<DotGeopointsDoc> dotGeopointsDocList;
private String xmlFileName;
private String tmpValue;
private DotGeopointsDoc currentDotGeopointsDoc;
private DotGeopointsDoc dotGeopointsDoc;
private String bookXmlFileName;
//you do not need constuctors here just a "setup method ex."
public void setUpMySaxParser(String bookXmlFileName) {
this.xmlFileName = bookXmlFileName;
dotGeopointsDocList = new ArrayList<DotGeopointsDoc>();
dotGeopointsDoc = new DotGeopointsDoc();
parseDocument();
}
private void parseDocument() {
// parse
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(xmlFileName, this);
} catch (ParserConfigurationException e) {
System.out.println("ParserConfig error");
} catch (SAXException e) {
System.out.println("SAXException : xml not well formed");
} catch (IOException e) {
System.out.println("IO error");
}
}
#Override
public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
if (elementName.equalsIgnoreCase("trkpt")) {
dotGeopointsDoc.setId(new ObjectId());
dotGeopointsDoc.setLat(attributes.getValue("lat"));
dotGeopointsDoc.setLon(attributes.getValue("lon"));
}
}
#Override
public void endElement(String s, String s1, String element) throws SAXException {
if (element.equals("trkpt")) {
dotGeopointsDocList.add(dotGeopointsDoc);
mongoTemplate.save(dotGeopointsDoc); // here I'm getting NullPointerException. My mongoTemplate is null
dotGeopointsDoc = new DotGeopointsDoc();
}
}
#Override
public void characters(char[] ac, int i, int j) throws SAXException {
tmpValue = new String(ac, i, j);
}
}

Related

JPA Entity not stored OneToMany relationship

i trie to run the following code.
But the child is not created to the parent Entity 'Erfasser'.
If i comment out the line erfasser.getErfasst().add(neu) everything works fine.
#PostConstruct
public void init() {
Erfasser erfasser = new Erfasser();
erfasser.setEmail("benjamin.koubik#auditweb.de");
erfasser.setPasswort("counting88");
gesamtAnzahl.einfuegenErfasser(erfasser);
Erfasst neu = new Erfasst();
neu.setDatum(new Date());
neu.setJuristische(1);
neu.setNatuerliche(0);
gesamtAnzahl.einfuegen(neu);
erfasser.getErfasst().add(neu);
gesamtAnzahl.update(erfasser);
}
Only the Erfasser itself is stored correctly in the DB.
#Entity
public class Erfasser implements Serializable {
private static final long serialVersionUID = 1L;
public Erfasser() {
super();
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int erfasser_id;
#Column(length = 50)
#Email(message = "Inkorrekt EMail")
private String email;
#Column(length = 30)
private String passwort;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(referencedColumnName = "erfasser_id", name = "erfasst_id_referenz")
private List<Erfasst> erfasst;
public int getErfasser_id() {
return erfasser_id;
}
public void setErfasser_id(int erfasser_id) {
this.erfasser_id = erfasser_id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPasswort() {
return passwort;
}
public void setPasswort(String passwort) {
this.passwort = passwort;
}
public List<Erfasst> getErfasst() {
return erfasst;
}
public void setErfasst(List<Erfasst> erfasst) {
this.erfasst = erfasst;
}
}
And here my SessionBeans:
AnzahlErfasstGesamtLocal.java
#Local
public interface AnzahlErfasstGesamtLocal {
public abstract List<Integer> gesamt();
public abstract List<Erfasst> gesamtNatuerlich();
public abstract List<Erfasst> gesamtJuristisch();
public abstract void einfuegenErfasser(Erfasser e);
public abstract void einfuegen(Erfasst e);
public abstract void update(Erfasser e);
public abstract void loeschen(Erfasst e);
}
AnzahlErfasstGesamt.java
#Stateless
#LocalBean
public class AnzahlErfasstGesamt implements AnzahlErfasstGesamtLocal {
#PersistenceContext
private EntityManager em;
public AnzahlErfasstGesamt() {
}
#Override
public List<Integer> gesamt() {
return null;
}
#Override
public List<Erfasst> gesamtNatuerlich() {
try {
TypedQuery<Erfasst> q = em.createQuery(
"SELECT COUNT(e) FROM Erfasst e WHERE e.natuerliche = 1 AND e.juristische = 0; ", Erfasst.class);
List<Erfasst> liste = q.getResultList();
if (!liste.isEmpty()) {
return liste;
} else {
return null;
}
} catch (NoResultException e) {
return null;
}
}
#Override
public List<Erfasst> gesamtJuristisch() {
try {
TypedQuery<Erfasst> q = em.createQuery(
"SELECT COUNT(e) FROM Erfasst e WHERE e.juristische = 1 AND e.natuerliche = 0; ", Erfasst.class);
List<Erfasst> liste = q.getResultList();
if (!liste.isEmpty()) {
return liste;
} else {
return null;
}
} catch (NoResultException e) {
return null;
}
}
#Override
public void einfuegen(Erfasst e) {
em.persist(e);
}
#Override
public void update(Erfasser e) {
em.merge(e);
}
#Override
public void loeschen(Erfasst e) {
em.remove(em.merge(e));
}
#Override
public void einfuegenErfasser(Erfasser e) {
em.persist(e);
}
}
There is nothing wrong with JPA - something is wrong in external code (and certainly with your description of the problem). For example I don't see where the actual erfasst list is created - if nothing happens in einfuegenErfasser (whatever that means), then you will get a NullPointerException while trying to add an element to a null list. Is that what happens?
The problem is the combination of JPA entity setup and the code using it. The JPA entity Erfasser has CascadeType.ALL, therefore the gesamtAnzahl.update(erfasser); updates the child entities erfasst with it. At the same time you do not setup the erfasser reference on the neu instance. You need to do something alog the line neu.setErfasser(erfasser) before gesamtAnzahl.update(erfasser);.
On separated line of concern, using the native German naming drives my head crazy, even though I am more German then English speaker.

Handling multiple client in java

I made simple client server chat program that support multiple client but i have a problem:`
public class Main extends Application {
public Button send;
public TextArea textarea;
public TextArea onlineuser;
public TextField usertext;
public static int maxUser = 100;
public boolean run=true;
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("server.fxml"));
primaryStage.setTitle("Server control ");
primaryStage.setScene(new Scene(root, 749, 494));
primaryStage.show();
}
public static void main(String[] args) throws IOException{
Server sv=new Server(1111);
launch(args);
}
class Server extends Thread {
private ServerSocket sv;
private ThreadServer[] clientconnect = new ThreadServer[maxUser];
public Server(int port) throws IOException {
this.sv = new ServerSocket(port);
start();
}
public void run() {
while (run) {
try {
Socket connect = this.sv.accept();
connectionThread(connect);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectionThread(Socket connection) {
for (int a = 0; a < maxUser; a++) {
if (this.clientconnect[a] == null) {
this.clientconnect[a] = new ThreadServer(connection, a);
break;
}
}
}
}
class ThreadServer extends Thread {
final private int userID;
final private Socket threadconnect;
public void run() {
while (run)) {
try {
PrintWriter out = new PrintWriter(threadconnect.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(threadconnect.getInputStream()));
textarea.appendText(in.readLine());
out.println(usertext.getText());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public ThreadServer(Socket connect, int ID) {
this.userID = ID;
this.threadconnect = connect;
}
}
I have client part works fine but i cant call my server class in main because it's not a static but i should use main also launch javafx gui part how can i solve this problem?

Logic issue on dynamic static Asyncallback - GWT

Im trying to test the Performance tip of : https://groups.google.com/forum/#!msg/google-web-toolkit/f9FLCEloW-c/3ZelaqGUGTcJ
I have more than 5 different Callbacks with different result object .
how can i creat a dynamic static class in only one static Class :
public class AsyncCallbacks
{
private static AsyncCallback<?> callback = null;
private AsyncCallbacks(){
}
private AsyncCallback<?> createCallback() {
if(callback == null) {
callback = new AsyncCallback(){
#Override
public void onFailure(Throwable caught)
{
// TODO Auto-generated method stub
}
#Override
public void onSuccess(Object result)
{
// TODO Auto-generated method stub
}
};
}
return callback;
}
}
public class Asyncs implements AsyncCallback<Object> {
private Dto1 dto1 = null;
private Dto2 dto2 = null;
private Object result = null;
#Override
public void onFailure(Throwable caught) {
// failed message
}
#Override
public void onSuccess(Object result) {
this.result = result;
}
public Object getSuccessObject() {
if (result instanceof Dto1) {
dto1 = (Dto1) result;
} else if (result instanceof Dto2) {
dto2 = (Dto2) result;
}
return result;
}
}

JsonProvider for Jersey 2.5 in Glassfish 4 does not mapping properties

I am using jersey as rest client, but I have problems when application is actually deployed as war on Glassfish 4. When I run it from test it works okay, but in deployed application mapping to POJO return all properties as null.
I tried MoxyJsonProvider, JacksonJsonProvider also custom GsonProvider, but result is same.
Client constructor:
public DockerClientImpl(String restApiUrl) {
restURL = restApiUrl;
restClient = ClientBuilder
.newBuilder()
.register(GsonProvider.class)
.build();
}
One of get methods:
#Override
public List<Container> getContainers(boolean all, boolean latest, int limit, boolean showSize, String since, String before) throws DockerException {
Response response = restClient
.target(restURL)
.path(CONTAINERS_LIST)
.queryParam("all", all)
.queryParam("limit", limit)
.queryParam("since", since)
.queryParam("before", before)
.queryParam("size", showSize)
.request(MediaType.APPLICATION_JSON)
.get();
switch (response.getStatus()) {
case 200:
LOGGER.info("Container list succesfully retrieved");
break;
case 400:
LOGGER.error("Bad request parameter");
throw new DockerException("Bad request parameter");
case 500:
LOGGER.error("Docker Server Error");
throw new DockerException("Docker Server Error");
default:
throw new DockerException("Unknown Error");
}
Type type = new TypeToken<Collection<Container>>() {
}.getType();
List<Container> result = response.readEntity(new GenericType<List<Container>>() { });
LOGGER.debug(String.format("Response: %s", result));
return result;
}
Container POJO:
#SerializedName("Id")
private String id;
#SerializedName("Command")
private String command;
#SerializedName("Image")
private String image;
#SerializedName("Created")
private long created;
#SerializedName("Status")
private String status;
#SerializedName("Ports")
private Port[] ports; //Example value "49164->6900, 49165->7100"
#SerializedName("SizeRw")
private int size;
#SerializedName("SizeRootFs")
private int sizeRootFs;
#SerializedName("Names")
private String[] names;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Port[] getPorts() {
return ports;
}
public void setPorts(Port[] ports) {
this.ports = ports;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getSizeRootFs() {
return sizeRootFs;
}
public void setSizeRootFs(int sizeRootFs) {
this.sizeRootFs = sizeRootFs;
}
public String[] getNames() {
return names;
}
public void setNames(String[] names) {
this.names = names;
}
And currently used Gson Provider:
#Provider
#Consumes({MediaType.APPLICATION_JSON, "text/json"})
#Produces({MediaType.APPLICATION_JSON, "text/json"})
public class GsonProvider implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private static final String UTF_8 = "UTF-8";
private Gson gson;
public GsonProvider() {
}
private Gson getGson() {
if (gson == null) {
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
return gson;
}
#Override
public boolean isReadable(Class<?> type, Type genericType,
java.lang.annotation.Annotation[] annotations, MediaType mediaType) {
return true;
}
#Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
try (InputStreamReader streamReader = new InputStreamReader(entityStream, UTF_8)) {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
return getGson().fromJson(streamReader, jsonType);
}
}
#Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
#Override
public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
#Override
public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8)) {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
getGson().toJson(object, jsonType, writer);
}
}
}
Output in tests:
Container{id=a9e3a67979d392a0e48d534db5184ce717b0629c4255d4dbc1373f5a9140df51, command=/bin/sh -c /usr/sbin/sshd -D, image=frantiseks/apac:latest, created=1388002251, status=Up About an hour, ports=[Lcz.utb.fai.apac.entity.Port;#69ac536b, size=0, sizeRootFs=0, names=[Ljava.lang.String;#3098cc00}
Output from deployed application:
[Container{id=null, command=null, image=null, created=0, status=null, ports=null, size=0, sizeRootFs=0, names=null}, Container{id=null, command=null, image=null, created=0, status=null, ports=null, size=0, sizeRootFs=0, names=null}]
So could someone tell me why it do not work in glassfish? Or what I am doing wrong?
Thanks.

Play2 How to manage the transaction from the service layer instead of action layer?

I am using Play2.1.1 Java with JPA2.0 with hibernate implementation.
to control the transaction by code instead of using #transactional like below is the normal JPA code style, Is there any way to work like below at Play? or how to use JPA.withtranaction() to do? I tried it, no idea how to pass in the parameter, I am not familiar with functional code. thanks a lot. Please give me some sample code based on below.
public void createActorB(final String email, final String psw) throws Throwable {
EntityManager manager = JPA.em();
try {
EntityTransaction ex = manager.getTransaction();
this.dbActor.setEmail(email);
this.dbActor.setCredential(psw);
manager.persist(this.dbActor);
ex.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ActorException(CODE.UNKNOWN, e);
} finally {
manager.close();
}
}
Now I change my code below to start transaction from service layer, It does not looks efficient, is there any other way to write? thanks
private void internalCreateActor(String email, String psw) throws ActorException {
if (StringUtils.isEmpty(email) || StringUtils.isEmpty(psw))
throw new ActorException(CODE.INVALIDE_PARAMETER);
try {
this.dbActor.setEmail(email);
this.dbActor.setCredential(psw);
this.dbActor.setCreateD(new Date());
JPA.em().persist(this.dbActor);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new ActorException(CODE.UNKNOWN, e);
}
}
public void createActor(final String email, final String psw, final String cellPhone, final Actor.TYPE type)
throws Throwable {
JPA.withTransaction(new Callback0() {
#Override
public void invoke() throws Throwable {
internalCreateActor(email, psw, cellPhone, type);
}
});
}
something like this:
public static User getUserByIdentity(final AuthUserIdentity identity) {
try {
return JPA.withTransaction(new play.libs.F.Function0<User>() {
public User apply() {
return User.findByAuthUserIdentity(identity);
}
});
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
After some time research, I write a method JPAUtil referring to JPA provided by Play which can use normally to control the transaction manually from the service layer actually everywhere.
public class JPAUtil {
static ThreadLocal<EntityManager> currentEntityManager = new ThreadLocal<EntityManager>();
/**
* Get the EntityManager for specified persistence unit for this thread.
*/
public static EntityManager em(String key) {
Application app = Play.application();
if (app == null) {
throw new RuntimeException("No application running");
}
JPAPlugin jpaPlugin = app.plugin(JPAPlugin.class);
if (jpaPlugin == null) {
throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
}
EntityManager em = jpaPlugin.em(key);
if (em == null) {
throw new RuntimeException("No JPA EntityManagerFactory configured for name [" + key + "]");
}
bindForCurrentThread(em);
return em;
}
/**
* Get the default EntityManager for this thread.
*/
public static EntityManager em() {
EntityManager em = currentEntityManager.get();
if (em == null) {
return em(Constants.DATASOURCEKEY);
}
return em;
}
/**
* Bind an EntityManager to the current thread.
*/
public static void bindForCurrentThread(EntityManager em) {
currentEntityManager.set(em);
}
public static void closeEM() {
EntityManager em = currentEntityManager.get();
if (em != null) {
em.close();
}
bindForCurrentThread(null);
}
public static void beginTransaction() {
em().getTransaction().begin();
}
public static void commitTransaction() {
em().getTransaction().commit();
}
}