Unable to save Node to Neo4j with Spring boot - java

I am trying to save a node into Neo4j database with Spring boot and getting the following Exception:
java.lang.IllegalArgumentException: Class class com.test.neo4j.model.Company is not a valid entity class. Please check the entity mapping.
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:77) ~[neo4j-ogm-core-3.2.11.jar:3.2.11]
at org.neo4j.ogm.session.delegates.SaveDelegate.save(SaveDelegate.java:51) ~[neo4j-ogm-core-3.2.11.jar:3.2.11]
at org.neo4j.ogm.session.Neo4jSession.save(Neo4jSession.java:480) ~[neo4j-ogm-core-3.2.11.jar:3.2.11]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
Below is my Entity class:
package com.test.neo4j.model;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
#NodeEntity
public class Company {
#Id
private String id;
private String name;
public Company() {}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Below is my repository:
package com.test.neo4j.repository;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import com.test.neo4j.model.Company;
public interface CompanyRepository extends Neo4jRepository<Company, String>{
}
I am Autowiring the repo in my service and calling save with it. Now, I have looked up the other answers and made sure of the following:
Package name does not contain any upper case character
Model class has got default constructor
id is explicitly set in the service
Am I missing anything else here?

The Company class is not part of the class scanning initiated at start of the application.
This can have various reasons:
You are using the Spring Data Neo4j auto starter without any special config for package scans. As a result only entity classes in this package and "sub"-packages will get scanned.
You manually configured the SessionFactory bean and the given package does not match the ("sub"-)package your class is in.

Related

Passing Dynamic collection name on Spring MongoRepository not working

I'm creating dynamic collections by using mongoTemplate in service layer. Upto this everything went well but when saving into collection dynamically makes issue. explaining here...
Service Layer
public void createCollection(String collectionName) {
mongoTemplate.createCollection(collectionName);
}
public Object updateLessonOrSurveyOrQuery(String courseID, int levelNo, CourseAsset courseAssetToUpdate) {
.....
courseAssetRepo.saveByCourseID(courseID, courseAssetToUpdate);
.....
}
Repo Layer
#Repository
public interface CourseAssetRepo extends MongoRepository<CourseAsset, String> {
ArrayList<CourseAsset> findAllByCourseID(String courseID);
void saveByCourseID( String courseID, CourseAsset courseAsset);
}
findAllByCourseID working but saveByCourseID not woking;
POJO class
#Data
public class CourseAsset {
private int level;
private String title;
private String courseID;
}
ERROR :
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'courseAssetRepo' defined in com.dotbw.learn.repo.CourseAssetRepo defined in #EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Could not create query for public abstract void com.dotbw.learn.repo.CourseAssetRepo.saveByCourseID(java.lang.String,com.dotbw.learn.model.CourseAsset); Reason: No property 'saveByCourseID' found for type 'CourseAsset'
i can understand repo expects CourseAsset Data inside the pojo class. But while saving how we can provide this value.
i have tried many way as ChatGPT said but nothing worked.

How to search in h2 database Play Framework 2.7.3?

I need to search in an h2 database for Company class instances that have a specific code, but I can't figure out how.
I have tried using the Finder class, but there don't seem to be any find methods in the version i am using except findbyid().
Here is the beginning of my Company class:
#Entity
public class Company extends Model {
#Id
public Integer id;
public String code;
public String name;
public String adress;
public String fiscalCode;
public String bankAccount;
public static Finder<Integer, Company> find = new Finder<>(Company.class);
Thank you!
Depending on the version of Play you are using I'd suggest to try the following:
Company.find.where().like("code", "%foo%").findList();
or
Define your finder
public class CompanyFinder extends Finder<Long,Company> {
public CompanyFinder() {
super(Company.class);
}
// Add finder methods ...
public Company byCode(String code) {
return query().eq("code", code).findOne();
}
}
Update your entity to reference this finder:
#Entity
public class Company extends BaseModel {
public static final CompanyFinder find = new CompanyFinder();
...
}
Call the finder:
Company c = Company.find.byCode("foo");

MOXy is only marshaling base class members in a collection

I have a base class declared something like:
package com.mystuff.surrogates;
import java.io.Serializable;
import java.util.UUID;
public class BaseClass implements Serializable {
private UUID id;
private String name;
public UUID getId() { return this.id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return thisname; }
public void setName(String name) { this.name = name; }
}
And a derived class which looks something like:
package com.mystuff.surrogates;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class DerivedClass extends BaseClass {
private String email;
public String getEmail() { return this.email; }
public void setEmail(String email) { this.email = email; }
}
Finally I have a class which I am trying to return as an object from a RESTful webservice call which includes a collection of BaseClass derived class instances and looks rather like:
package com.mystuff.surrogates;
import java.util.ArrayList;
import java.util.List;
public class Response {
List<BaseClass> objectList;
public List<BaseClass> getObjectList() { return this.objectList; }
public void setObjectList(List<BaseClass> objectList) { this.objectList = objectList; }
public void addObject(BaseClass obj) {
if (this.objectList == null) {
this.objectList = new ArrayList<>();
}
this.objectList.add(obj);
}
}
When marshaling this into either XML or JSON, only the members in the base class are included. How do I get Jersey / MOXy to marshal the entire class instance rather than just the base class members? While I have only shown here one derived class, I have several others I would like to potentially chose from to return in the list, so simply using List<DerivedClass> isn't an option since it would preclude returning any of those other classes in the list.
Other information:
Netbeans 8.0.2
Glassfish 4.1 (locally hosted)
Oracle JDK 8U31 (64 bit Windows)
Java EE 7
You'll need to use #XmlSeeAlso so the other classes are binded.
#XmlSeeAlso({DerivedClass.class})
public class BaseClass {
This may not get you the exact desired result, as the marshalled data will have a reference to the type. For instance with XML, you will see
<objectList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="derivedClass">
and JSON you will see
{"objectList":[{"type":"derivedClass",...
You can have a look at this answer for an idea of how to get rid of the type property if it's undesired.
As far as the JSON is concerned, using Jackson will not have this behavior. You can simply use jersey-media-json-jackson, which Glassfish also comes shipped with (you can add it as a dependency in a provided scope), and just register the JacksonFeature with the application.

Error on client side while calling a business method on server side returning managed entity

My client application is a standalone java application using Netbeans RCP. The client application connect to a remote EJB mounted on a Glassfish server.
On the server side, i have a business method (i made for testing) that's supposed to take an instance of an entity (this entity is not persisted or managed yet), persist it (using the persit of the EntityManager).
Here is how this method looks like:
#Override
public TestLinkEntity test(TestLinkEntity c) {
em.persist(c);
return c;
}
Called from the client side like this:
TestLinkEntity c = remote.test(new TestLinkEntity());
Here is the TestLinkEntity declaration:
#Entity
public class TestLinkEntity implements AltEntity, Serializable {
private Set<TestAppEntity> links = new HashSet<TestAppEntity>();
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#OneToMany(mappedBy="links")
public Set<TestAppEntity> getLinks() {
return links;
}
}
And now the TestAppEntity used in the one to many relationship.
#Entity
public class TestAppEntity implements Serializable, AltEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String test;
public TestAppEntity() {
}
#Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
The problem i'm facing is when i try to call the business method from the client (as shown above) i get a huge and quite unreadable exception on client side and only on client side. No exception logged on the Glassfish logs and the entity (TestLinkEntity)and potential links (TestAppEntity) are stored in the data base.
I pasted the exception here.
Here are few things i have noticed.
The exception only happen when i try to return a managed entity. If i replace the em.persist() by em.merge and do not return the new entity returned by merge for example, the exception will never be raised. e.g do something like:
#Override
public TestLinkEntity test(TestLinkEntity c) {
em.merge(c);
return c;
}
The exception only happen when the entity returned contains the one to many relationship. e.g something like the following code snippet will not raise an exception:
#Override
public TestAppEntity test(TestAppEntity c) {
em.persist(c);
return c;
}
TestAppEntity does not contain any relationship.
Things i'm sure:
TestAppEntity and TestLinkEntity are the same on both client and server sides.
EDIT:
Due to the answer of #James, i'm now wondering what is the difference between the package javax.persistence in eclispelink.jar and in javaee.jar. Should i include both?
Including both cause troubles (maybe due to the fact that package name in both jars are the same).
error: in class file javax/persistence/NamedQuery.class(javax/persistence:NamedQuery.class): unknown enum constant javax.persistence.LockModeType.NONE
Note: Attempting to workaround javac bug #6512707
warning: No processor claimed any of these annotations: [javax.ejb.Remote]
error: in class file j javax/persistence/NamedQuery.class(javax/persistence:NamedQuery.class): unknown enum constant javax.persistence.LockModeType.NONE
It seems to be some bug in the CORBA serialization you are using.
My guess is you don't have the eclipseLink.jar on your client, but you need it. As objects read from the database will contains special LAZY collections instances.

org.hibernate.exception.SQLGrammarException: could not execute query

I use play framework !! But when I run my project it give me this
org.hibernate.exception.SQLGrammarException: could not execute query
who can help me ?
this is my model:
package models;
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
import play.db.jpa.Model;
#Entity
#Table(name="GxkAccount")
public class GxkAccount extends Model {
private String Account;
private String Psw;
public String getAccount() {
return Account;
}
public void setAccount(String account) {
Account = account;
}
public String getPsw() {
return Psw;
}
public void setPsw(String psw) {
Psw = psw;
}
public static List<GxkAccount> GetList()
{
List<GxkAccount> infoList=GxkAccount.findAll();
return infoList;
}
}
You are completely missing the mapping annotations for the properties of your class.
P.S. Please try to follow the Java naming conventions
Using mysql, we also faced this type of issue. We found in play framework application.conf:
jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
we replaced this with
jpa.dialect=org.hibernate.dialect.MySqlDialect.
This solved the problem. If you are facing this issue you can try out this configuration setting.
We also faced the same issue. We were having create in the xml and #GeneratedValue on the id column. The resolution is remove the #GeneratedValue annotation and put the value of the id manually, also the jpa takes long by default so give long value e.g 1l.
To do the auto generation follow some another rule.
The issue around the JPA related auto generated Id is resolved as below:
Modify the Person.java model class to have the following annotations for the Id attribute:
#Id
#TableGenerator(name="TABLE_GEN",table="T_GENERATOR",pkColumnName="GEN_KEY",pkColumnValue="TEST",valueColumnName="GEN_VALUE",initialValue=1,allocationSize=1)
#GeneratedValue(strategy=GenerationType.TABLE, generator="TABLE_GEN")
public Long Id;
This will create a table in the mysql schema called T_GNERATOR which will have the tracking of the next value for Id and JPA over hibernate knows how to retrieve this value. The assumption is that the initial value for the Id is 1 and it is incremented by 1 on each new insertion into it as is obvious from the attributes of the annotation.

Categories

Resources