Entity throw no method exception - entity

I am building a simple JavaEE project and I keep getting the NoMethodFoundException: Faculty._persistence_set_customers(Customer).
The faculty entity has a oneToMany relationship with Customer entity. And the exception disappear when I removes that relationship. What could be the reason for this? Why is it asking for this method?
The exception is as followed:
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: An internal error occurred while accessing method [_persistence_set_customers] on class [class hb.model.entity.Faculty].
Internal Exception: java.lang.NoSuchMethodException: hb.model.entity.Faculty._persistence_set_customers(hb.model.entity.Customer)
Descriptor: RelationalDescriptor(hb.model.entity.Faculty --> [DatabaseTable(USERS)])
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl$1.handleException(EntityManagerSetupImpl.java:692)
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.handleException(AbstractSynchronizationListener.java:275)
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:170)
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:452)
The source code of the Faculty entity is as followed:
package hb.model.entity;
import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
/**
*
* #author hasee
*/
#Entity
public class Faculty extends Users implements Serializable {
private static final long serialVersionUID = 1L;
#OneToMany(mappedBy = "faculty")
private ArrayList<Customer> customers;
private String position;
public Faculty() {
}
public ArrayList<Customer> getCustomers() {
return customers;
}
public void setCustomers(ArrayList<Customer> customers) {
this.customers = customers;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
Many thanks,

After checking some example code: I realize all the relationship related to OneToMany or ManyToMany use List<> instead of ArrayList<>. After making this change the application worked just fine, however the reason is still unknown.

Related

eclipselink/jpa inheritance problems

I am using spring boot (2.0.0) with eclipse link to persist data (over 500 entity classes) to a postgres db (6.5). Thats works very well. For receiving the data over REST I build an other spring boot application. Here I have some inheriance problem with JPA (sorry for my drawing):
Class C and class D (abstract) inherit from class B. Class A have a reference (attribute1) to class B. This attribute is an instance of entity class E, which inherit from abstract class D. I am using inheritance strategy table per class. Every class using the annotation Entity with the table name. In the database, table from class A have a correct foreign key to table from class E, but if I want to read the data the attribute1 is null. I see from the log level that eclipse link only look inside table from class C. How can I resolve this problem?
Greets Benjamin
here are the classes, class E:
#Entity(name="ep_core_voltagelevel")
public class VoltageLevel extends EquipmentContainer {
#Embedded
#AttributeOverrides(#AttributeOverride(name="value", column=#Column(name="highVoltageLimit_value")
)
)
private myPackage.DomainProfile.Voltage highVoltageLimit;
public myPackage.DomainProfile.Voltage getHighVoltageLimit() {
return highVoltageLimit;
}
public void setHighVoltageLimit(myPackage.DomainProfile.Voltage parameter) {
this.highVoltageLimit = parameter;
}
#Embedded
#AttributeOverrides(#AttributeOverride(name="value", column=#Column(name="lowVoltageLimit_value")
)
)
private myPackage.DomainProfile.Voltage lowVoltageLimit;
public myPackage.DomainProfile.Voltage getLowVoltageLimit() {
return lowVoltageLimit;
}
public void setLowVoltageLimit(myPackage.DomainProfile.Voltage parameter) {
this.lowVoltageLimit = parameter;
}
#ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(nullable=false, name="basevoltage_id")
private BaseVoltage baseVoltage;
public BaseVoltage getBaseVoltage() {
return baseVoltage;
}
public void setBaseVoltage(BaseVoltage parameter) {
this.baseVoltage = parameter;
}
#ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(nullable=false, name="substation_id")
private Substation substation;
public Substation getSubstation() {
return substation;
}
public void setSubstation(Substation parameter) {
this.substation = parameter;
}
}
Class D:
#Entity(name = "ep_core_equipmentcontainer")
public abstract class EquipmentContainer extends ConnectivityNodeContainer {
}
Class B:
#Entity(name="ep_core_connectivitynodecontainer")
public abstract class ConnectivityNodeContainer extends PowerSystemResource {
}
Class A:
public class ConnectivityNode extends IdentifiedObject {
#ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(nullable=false, name="connectivitynodecontainer_id")
private ConnectivityNodeContainer connectivityNodeContainer;
public ConnectivityNodeContainer getConnectivityNodeContainer() {
return connectivityNodeContainer;
}
public void setConnectivityNodeContainer(ConnectivityNodeContainer parameter) {
this.connectivityNodeContainer = parameter;
}
}

Wicket: how to get rid of WicketNotSerializableException?

Ok, so here is the code for the page
public class ViewDocument extends BasePage{
private List<WeinSyncFileContent> transactions;
....
public ViewDocument(){
transactions = ....;
....
listContainer.add(listView = new ListView<WeinSyncFileContent>("transactions", transactions){
#Override
public void populateItem(final ListItem<WeinSyncFileContent> item)
{
....
}
});
}
}
The page does get displayed but I get errors:
Error serializing object class kz.wein.wicket.pages.documents.ViewDocument
and it's complaining about the transactions field:
transactions [class=java.util.ArrayList$SubList] <----- field that is not serializable
Also I want to note that objects I am displaying in the list are initially taken from library and are not serializable. Wicket wants serializable objects inside lists so to deal with it I take each object and make it serializable with class like this
public class WeinSyncFileContent extends SyncFileContent implements Serializable{
public WeinSyncFileContent(SyncFileContent obj){
... setting fields ...
}
}
so initially I get SyncFileContent objects (that are not serializable)
What can I do about the errors?
You are getting this error because any field level variables in your Wicket pages will be serialized. So its probably a good idea to not have any non-serializable objects as field level variables. There must be an object in your WeinSyncFileContent that is not serializable which is why you are getting this error.
You may want to instead use models to load your list so something like:
public ViewDocument(){
...
listContainer.add(new ListView<WeinSyncFileContent>(
"transactions",
new LoadableDetachableModel<List<WeinSyncFileContent>>() {
protected List<WeinSyncFileContent> load() {
return ...;
}
})
{
#Override
public void populateItem(final ListItem<WeinSyncFileContent> item)
{
....
}
});
}

Failed to create EJB in REST service

I have a problem with injecting EJB inside of a REST service (using jersey on glassfish 3.2 server) and I'm puzzled.
I have an EJB interface declared as:
import javax.ejb.Local;
#Local
public interface TestServiceLocal {
public String getText();
}
and the class bean that implements it:
import javax.ejb.Local;
import javax.ejb.Stateless;
/**
* Session Bean implementation class TestService
*/
#Stateless
#Local(TestServiceLocal.class)
public class TestService implements Serializable, TestServiceLocal {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TestService() {
// TODO Auto-generated constructor stub
}
#Override
public String getText() {
return this.getClass().getName();
}
}
The REST service looks like:
#Path("/service")
#Stateless
public class TestRestService {
#EJB(beanName="TestService")
private TestServiceLocal testService;
public TestRestService () {
}
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/events")
public String getText() {
return testService.getText();
}
}
The problem is that when the REST service is called the bean cannot be created:
SEVERE: EJB5070: Exception creating stateless session bean : [TestRestService]
WARNING: EJB5184:A system exception occurred during an invocation on EJB TestRestService, method: public java.lang.String TestRestService.getText()
WARNING: javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:454)
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2547)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1899)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy839.getText(Unknown Source)
I had already took a look at the answers posted here but none of them seemed to work for me. Any help will be appreciated. Thank you!
PS: I forgot to mentioned (don't know if it's relevant). My project is created under eclipse Juno as Dynamic Web Project.

Audit for OneToOne attributes

Using Glassfish 3.1.2 and eclipselink 2.2.0.
I have to track changes for following entity:
#Entity
#EntityListeners({AuditListener.class})
#Customizer(AuditListener.class)
public class Client extends Person {
...
#OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private ConsumptionRoomAndPost consumptionRoomAndPost;
...
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Document> documentList;
...
AuditListener:
public class AuditListener extends DescriptorEventAdapter implements DescriptorCustomizer {
...
#Override
public void postMerge(DescriptorEvent event) {
if (event.getChangeSet() != null) {
...
}
}
}
This works for a Document list, changeSet is not empty,
but not for ConsumptionRoomAndPost. The changeSet is empty.
Of course I can add own listener ConsumptionRoomAndPostAuditListener for ConsumptionRoomAndPost but for a audit i need a client information and than I have a problem to provide this client information to a ConsumptionRoomAndPostAuditListener.
Solved.
After changing relationships to bidirectional, eclipse link tracks changes for all attributes.
I have added to entity ConsumptionRoomAndPost:
public class ConsumptionRoomAndPost {
...
#OneToOne(mappedBy = "consumptionRoomAndPost", cascade = CascadeType.ALL)
private Client client;
...
}
its all.

How to inject a Session Bean into a Message Driven Bean?

I'm reasonably new to Java EE, so this might be stupid.. bear with me pls :D
I would like to inject a stateless session bean into a message-driven bean. Basically, the MDB gets a JMS message, then uses a session bean to perform the work. The session bean holds the business logic.
Here's my Session Bean:
#Stateless
public class TestBean implements TestBeanRemote {
public void doSomething() {
// business logic goes here
}
}
The matching interface:
#Remote
public interface TestBeanRemote {
public void doSomething();
}
Here's my MDB:
#MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
#EJB
private TestBean testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}
So far, not rocket science, right?
Unfortunately, when deploying this to glassfish v3, and sending a message to the appropriate JMS Queue, I get errors that glassfish is unable to locate the TestBean EJB:
java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/mvs.test.TestController/testBean' in SerialContext [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'mvs.test.TestBean#mvs.test.TestBean' [Root exception is javax.naming.NamingException: Lookup failed for 'mvs.test.TestBean#mvs.test.TestBean' in SerialContext [Root exception is javax.naming.NameNotFoundException: mvs.test.TestBean#mvs.test.TestBean not found]]]
So my questions are:
is this the correct way of injecting a session bean into another bean (particularly a message driven bean)?
why is the naming lookup failing?
Could you try to define things like this:
#Remote
public interface TestBeanRemote {
public void doSomething();
}
#Stateless(name="TestBeanRemote")
public class TestBean implements TestBeanRemote {
public void doSomething() {
// business logic goes here
}
}
And then in the MDB:
#MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
#EJB(beanName="TestBeanRemote")
private TestBeanRemote testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}
If this work, I'll try to provide an explanation :)
I think the problem of the very first example is that you are trying to inject the implementation of the EJB and not its interface. The local no-interface view of EJB 3.1 is just possible if you do not define any interface, not even a remote one. So changing the injection point to the following should work out:
#EJB
private TestBeanRemote testBean;
If you are using your application within a non clustered environment, so single JVM, you should think about changing the interface to #Local. As soon as you are accessing EJBs using their remote interface, you are getting a lot of overhead. Parameters and return values can not be accessed by reference anymore, but by value, as they are always copied (specification says so). This might lead to performence issues when dealing with more complex objects.
Hoped that helped.
It seems that my problem was related to Inversion of Control and caused by my lack of knowledge and Netbeans' suggestions for Class/Interface names.
I found out that - in order to find the the right bean and the right interface - I should name them properly. Here's what works:
#Remote
public interface Test {
public void doSomething();
}
#Stateless
public class TestBean implements Test {
public void doSomething() {
// business logic goes here
}
}
And in the MDB I access 'Test' not 'TestBean':
#MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
#EJB
private Test testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}
Ok, I found out that if I add the annotation #LocalBean to the session bean, it works. What the ...?