I've developed a simple code that displayes employee name by using Jpa's one of CRUD operations(find) on entity classes "Employee"& "Department" it worked properly while running the code , but the real problem came when I created a jar file from the application, an exception appeared from the jar file , I wrote the exception in a txt file
Here is the Employee class
package com.tutorialspoint.eclipselink.entity;
import java.util.*;
import javax.persistence.*;
#Entity
public class Employee {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private int eid;
#Temporal(TemporalType.TIMESTAMP)
private java.util.Date dop;
private String ename;
private double salary;
private String deg;
#OneToOne(targetEntity = Department.class)
private Department dept;
#OneToMany (targetEntity = Staff.class)
private ArrayList<Staff> staffs;
public Employee(int eid, String ename, double salary, String deg) {
super( );
this.eid = eid;
this.ename = ename;
this.salary = salary;
this.deg = deg;
}
public Employee( ) {
super();
}
public Date getDop() {
return dop;
}
public void setDop(Date dop) {
this.dop = dop;
}
public int getEid( ) {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
public String getEname( ) {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public double getSalary( ) {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getDeg( ) {
return deg;
}
public void setDeg(String deg) {
this.deg = deg;
}
public ArrayList<Staff> getStaffs() {
return staffs;
}
public void setStaffs(ArrayList<Staff> staffs) {
this.staffs = staffs;
}
}
and here is the class that displays employee name and degree
public void findEmployee(){
try{
EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "Eclipselink_JPA" );
EntityManager entitymanager = emfactory.createEntityManager();
Employee employee = entitymanager.find( Employee.class, 204 );
JOptionPane.showMessageDialog(null, employee.getEname()+
"=>"+employee.getDeg());
}catch(Exception ex){
JOptionPane.showMessageDialog(null,ex.getMessage());
displayMsg(ex.getMessage());
}
}
public void displayMsg(String msg){
// i made this method to display the exception in a txt file
File f = new File("E:\\bug2.txt");
FileWriter fw = new FileWriter(f);
PrintWriter pw = new PrintWriter(fw);
pw.println(msg);
pw.flush();pw.close();
}
and here is the exception
"
Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [Eclipselink_JPA] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions:
Exception [EclipseLink-1] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The attribute [teacherSet] is not declared as type ValueHolderInterface, but its mapping uses indirection.
Mapping: org.eclipse.persistence.mappings.ManyToManyMapping[teacherSet]
Descriptor: RelationalDescriptor(com.tutorialspoint.eclipselink.entity.Clas --> [DatabaseTable(CLAS)])
Exception [EclipseLink-1] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The attribute [clasSet] is not declared as type ValueHolderInterface, but its mapping uses indirection.
Mapping: org.eclipse.persistence.mappings.ManyToManyMapping[clasSet]
Descriptor: RelationalDescriptor(com.tutorialspoint.eclipselink.entity.Teacher --> [DatabaseTable(TEACHER)])
Exception [EclipseLink-1] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The attribute [staffs] is not declared as type ValueHolderInterface, but its mapping uses indirection.
Mapping: org.eclipse.persistence.mappings.ManyToManyMapping[staffs]
Descriptor: RelationalDescriptor(com.tutorialspoint.eclipselink.entity.Employee --> [DatabaseTable(EMPLOYEE)])
Runtime Exceptions:
--------------------------------------------------------- "
so what can be done?? knowing that the program works well when running the code from IDE but this exception happens when i built it and created jar file and ran the jar file
Exceptions that involve interfaces like ValueHolders and indirection is most likely a case of problems due to entity weaving.
Entity weaving is a process of modifying the compiled entities' bytecode so that they implement more interfaces and add new methods such that they can handle things like indirection and lazy-loading, among other features.
Is your IDE Oracle JDeveloper? It is one of the IDEs that, by default, have a run configuration that does this automatically, so that your entities work correctly. This can be configured in other IDEs in a similar manner - by adding -javaagent:<path to eclipselink JAR> as a program argument (or Java Option in some IDEs). Check this blog post for some quick info.
It might the be case in your deployment that Eclipselink's dynamic (runtime) weaving has failed (or is incomplete for some reason). Perhaps you should consider static weaving before the entities are packaged into the deployment artifact.
More info on doing so here: https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving
thanks , i found out the problem , it was in declaring the ArrayList of staff , it has a problem when I persist Collection declared as ArrayList or HashSet , I should declare it as the super interface eg Set or List ,so I modified it to
#OneToMany (targetEntity = Staff.class)
private List<Staff> staffs;
so, it worked very well and when I built the jar file it worked without any problems
Related
I must run project with JEE and EclipseLink 2.6.1. Maven successfully compiles the project, but when I put . jar on Payara and try to run it it gets problems of the type:
The abstract schema type 'NetServer'; is unknown.
The state field path 'netserver.active'; cannot be resolved to a valid type.
The problem occurs in queries with all entities with annotations #DiscriminatorValue. Entity looks like this:
Main class (Servers) :
#Entity
#Table("Servers")
#DiscriminatorColumn(
name = "SERVER_TYPE",
discriminatorType = DiscriminatorType.STRING
)
#DiscriminatorValue("servers")
public class Servers{
#Id
private Long id;
private String name;
private String hostname;
private Boolean active;
//getters& setters
}
Netserver:
#Entity
#DiscriminatorValue("netserver")
public class NetServer extends Server{
private String url;
public Netserver();
public Netserver(Server server){super(server);}
//getters&setters
}
And I wonder what the problem is that he throws away exceptions?
I have a simple project with the classes below defined. It works just fine in spring-boot 1.5.4, spring-data-commons 1.13, and spring-data-jpa 1.11.
When I upgrade to spring-boot 2.0.0.M5, spring-data-commons 2.0.0 and spring-data-jpa-2.0.0, I get a PropertyReferenceException at startup that says "No property delete found for type SimpleEntity!" Unfortunately, I can't get the stack trace out of
the computer I get the error in, it is very locked down for security.
Any ideas? Other posts I found don't seem to match my situation.
Here are the classes (altered the names, but you get the idea):
package entity;
#MappedSuperclass
public abstract class BaseEntity implements Serializable {
....
}
package entity;
#Entity
#Table(schema = "ENTITIES", name = "SIMPLE")
public class SimpleEntity extends BaseEntity {
#Column(name = "ID")
private Long id;
#Column(name = "CODE")
private String code;
#Column(name = "NAME")
private String name;
... getters and setters ...
}
package repository;
imoport org.springframework.data.repository.Repository
public interface SimpleRepository extends Repository<SimpleEntity, Long> {
public SimpleEntity save(SimpleEntity entity);
public List<SimpleEntity> save(List<SimpleEntity> entities);
public void delete(Long id);
public SimpleEntity findOne(Long id);
public List<SimpleEntity> findAllByOrderByNameAsc();
public List<SimpleEntity> findByCode(String code);
public List<SimpleEntity> findByNameIgnoreCaseOrderByNameAsc(String name);
}
Turns out there is a breaking change in Spring Data 2.0 CrudRepository interface. The error I received occurs under the following conditions:
You have a 1.x Sping Data project
You have an interface that extends Repository directly, not a subinterface like CrudRepository
Your Repository subinterface declares the "void delete(ID)" method found in CrudRepository (in my case "void delete(Long)"
You update to Spring Data 2.x
The problem is that CrudRepository in 2.x no longer has a "void delete(ID)" method, it was removed, and a new method "void deleteById(ID)" was added.
When Spring data sees a delete method signature it doesn't recognize, it produces an error about your entity class missing a delete property - this is true of both 1.2 and 2.x.
I have this entity
#Entity
public class ContactList extends Base {
private static final long serialVersionUID = BaseEntity.serialVersionUID;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Collection<User> contacts = new HashSet<User>();
public ContactList() {
}
public Collection<User> getContacts() {
return contacts;
}
public void setContacts(Collection<User> contacts) {
this.contacts = contacts;
}
}
and whatever method I call from the Spring Data repository, like findAll(), I get this error
java.lang.NullPointerException: null
at org.datanucleus.store.rdbms.RDBMSStoreManager.assertCompatibleFieldType(RDBMSStoreManager.java:1005) ~[datanucleus-rdbms-4.1.1.jar:na]
at org.datanucleus.store.rdbms.RDBMSStoreManager.getBackingStoreForField(RDBMSStoreManager.java:965) ~[datanucleus-rdbms-4.1.1.jar:na]
at org.datanucleus.store.rdbms.query.BulkFetchExistsHelper.getSQLStatementForContainerField(BulkFetchExistsHelper.java:93) ~[datanucleus-rdbms-4.1.1.jar:na]
at org.datanucleus.store.rdbms.query.JPQLQuery.compileQueryFull(JPQLQuery.java:894) ~[datanucleus-rdbms-4.1.1.jar:na]
at org.datanucleus.store.rdbms.query.JPQLQuery.compileInternal(JPQLQuery.java:296) ~[datanucleus-rdbms-4.1.1.jar:na]
at org.datanucleus.store.query.Query.executeQuery(Query.java:1801) ~[datanucleus-core-4.1.1.jar:na]
at org.datanucleus.store.query.Query.executeWithMap(Query.java:1747) ~[datanucleus-core-4.1.1.jar:na]
at org.datanucleus.api.jpa.JPAQuery.getResultList(JPAQuery.java:197) ~[datanucleus-api-jpa-4.1.1.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:77) ~[spring-data-jpa-1.3.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:55) ~[spring-data-jpa-1.3.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:95) ~[spring-data-jpa-1.3.0.RELEASE.jar:na]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:85) ~[spring-data-jpa-1.3.0.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:312) ~[spring-data-commons-1.5.0.RELEASE.jar:na]
Any idea why?
I also tried adding targetEntity = User.class to #ManyToMany.
I'm using DataNucleus 1.4.1.
I found in the log the following lines that could be relevant:
DataNucleus.Datastore.Schema - DEBUG: Field [ContactList.contacts] -> Column(s) [contactlist.contacts] using mapping of type "org.datanucleus.store.rdbms.mapping.java.TypeConverterMapping" (org.datanucleus.store.rdbms.mapping.datastore.VarCharRDBMSMapping)
...
DataNucleus.Persistence - WARN : Member ContactList.contacts in table=contactlist has mapping=org.datanucleus.store.rdbms.mapping.java.TypeConverterMapping#6296ccf7 but expected mapping type=class org.datanucleus.store.rdbms.mapping.java.CollectionMapping
The problem was that a Converter was automatically applied. But I think this is an issue with DataNucleus, because that converter was declared something like this
public class ListOfMyEnumsToStringAttributeConverter
extends CollectionOfEnumsToStringAttributeConverter<MyEnum, List<MyEnum>>
implements AttributeConverter<List<MyEnum>, String>
Another issue with DataNucleus is that NPE is thrown even though a warning/error message should be logged.
And last, but not least, when a converter is automatically applied and this leads to an error, the converter class should be part of the log message.
I'm doing a POC on a Hibernate OGM implementation for Neo4j. In doing this, I've created the following objects:
#Entity
public class AutoDealership {
private String name;
public AutoDealership(String nam){
this.name = nam;
}
#Id
public String getName(){
return name;
}
private void setName(String n){
name = n;
}
private List<Vehicle> vehicle = new ArrayList<Vehicle>();
#OneToMany(mappedBy="autoDealership")
public List<Vehicle> getVehicle(){
return vehicle;
}
private void setVehicles(List<Vehicle> v){
this.vehicle = v;
}
}
And a Vehicle class:
public abstract class Vehicle {
protected AutoDealership autoDealership;
abstract int getValue();
#ManyToOne
public abstract AutoDealership getAutoDealership();
private void setValue(int v){
}
}
Which is extended into classes that have simple implementations. I run this code as follows:
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
OgmSession session =em.unwrap(OgmSession.class);
Camry camry1 = new Camry("Joe");
Camry camry2 = new Camry("Elvis");
Silverado s = new Silverado("TX");
Maserati mas = new Maserati();
mas.setStatus("Massive");
session.saveOrUpdate(camry1);
session.saveOrUpdate(camry2);
session.saveOrUpdate(s);
session.saveOrUpdate(mas);
AutoDealership a = new AutoDealership("Slick Willie's");
session.saveOrUpdate(a);
camry1.setAutoDealership(a);
camry2.setAutoDealership(a);
mas.setAutoDealership(a);
s.setAutoDealership(a);
tx.commit();
em.close();
emf.close();
When I run this, it fails with :
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: ogm-neo4j] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1239)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:855)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75)
at org.hibernate.ogm.jpa.HibernateOgmPersistence.createEntityManagerFactory(HibernateOgmPersistence.java:62)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at dogs.TestClass.main(TestClass.java:22)
Caused by: org.hibernate.AnnotationException: Use of #OneToMany or #ManyToMany targeting an unmapped class: cars.AutoDealership.vehicle[cars.Vehicle]
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1134)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:793)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:728)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
If I comment out anything related to getting the vehicles from AutoDealership, the code compiles and works, and successfully inserts nodes into the database. I've tried to change the mappedBy target to no avail.
It turns out that the problem was that I had to declare Vehicle as an Entity.
I am trying to learn MongoDB and in the same time write a simple REST application using Spring framework.
I have a simple model:
#Document
public class Permission extends documentBase{
#Indexed(unique = true)
private String name;
public Permission(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then I have a simple DAO:
#Repository
#Transactional
#Profile({"production","repositoryTest","mongoIntegrationTest"})
public class DaoImpl implements DAO {
#Autowired
protected MongoTemplate mongoTemplate;
public <T> T addObject(T object) {
mongoTemplate.insert(object);
return object;
}
The I have my integration tests:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:mvc-dispatcher-servlet.xml", classpath:IntegrationContext.xml"},loader = TestXmlContextLoader.class)
#ActiveProfiles("mongoIntegrationTest")
public class RepositoryIntegrationTest extends AccountTestBase{
#Autowired DAO repository;
#Autowired WebApplicationContext wac;
#Test
public void AddPermission() {
Permission permission_1 = new Permission("test");
Permission permission_2 = new Permission("test");
repository.addObject(permission_1);
repository.addObject(permission_2);
}
}
My configuration:
<!-- MongoDB host -->
<mongo:mongo host="${mongo.host.name}" port="${mongo.host.port}"/>
<!-- Template for performing MongoDB operations -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"
c:mongo-ref="mongo" c:databaseName="${mongo.db.name}"/>
I am expecting that, on adding "permission_2" their would be a exception thrown from MongoDB, which would be translated by Spring,, and catched as a DataAccessException in the DAO.
Looking at the log files from MongoDb I can see that a duplicated exception is thrown but it never reaches my DAO.
So,, I guess I am doing something wrong,,, but at the moment,, I am blind to my own misstakes.
//lg
Make sure you configure the WriteConcern of the MongoTemplate to something non-default (e.g. WriteConcern.SAFE). By default MongoDB is in fire-and-forget mode and does not throw exceptions on index violations or server errors in general.
Still struggling with this.
Finnally I succeded to get the exeption translation working. MongoDb throws a exception which is translated to Spring Data exception.
Now I am stuck with another problem.
My DAO shown above has also the following code:
#ExceptionHandler(DataAccessException.class)
public void handleDataAccessException(DataAccessException ex) {
// For debug only
DataAccessException test = ex;
test.printStackTrace();
}
I was expecting this code to catch the exception thrown,, but this is not the case.
Why not?
//lasse