When you are creating a new view the #Named annotation should be used. However, if the view should be an extension of a class that already exists, how should this be achieved. To overwrite a method in the class I use the following:
#ViewScoped
#Specializes
public class classB extends class A{
#Override
public String save(){
}
}
This allows me to keep the already generated entity.
But the view needs to have the following annotations:
#Named
#ViewScoped
#URLMapping()
public class classB extends class A{
//content
}
How should this be achieved in one class? Given the two annotations cannot coexist?
The answer to this question depends on how the entity was originally created. If you are extending a class that manages an entity, you must create a separate view. That means one named class that is an extension of the class managing the entity.
After this, you must create a correlating JSF page to that new named view that was created.
If there is a transfer of information, you must create a proper extended class with the specializes annotation to have access to the entity.
If you attempt to manipulate the entity in the new view class you will cause a merge error because the program already thinks the entity exists in the database.
Related
I have a Spring bean (ChildBean extends Parent) which is extending an abstract class (Parent implements Runnable).
public abstract class Parent implements Runnable {
public final void run() {
// some code
}
public int overridenFunct() {
// some code
}
}
Child bean class variant which causes ClassCastException:
#Transactional
#Scope("prototype")
#Service("beanName")
public class ChildBean extends Parent {
#Override
public int overridenFunct() {
// some diff code
}
}
Everything works fine until I override public non-abstract method from parent class in child bean. After that a ClassCastException is thrown when I'm trying to create an instance of that bean.
Parent p = (Parent) appContext.getBean("beanName");
Bean object returned by getBean() is a ChildBean class instance (checked with debugger). Why does casting ChildBean object to its abstract parent class Parent not work?
So, without an overridenFunct() implemented in ChildBean everything works fine.
Could someone please tell what is the problem here?
UPDATE:
Changing method overridingFunct() to protected fixes the issue. But what if I need to override a public method? Is that allowed? I'm using Spring 3.2.8
UPDATE2:
Well, I didn't get to the point why overriding public method in abstract parent causes ClassCastException. As the resolution I did the following: created an interface with all public methods with common logic, an abstract class, which implements that interface and all "common" methods. Then all the child beans are extended from that abstract class, implementing its specific logic.
For anyone that may encounter this error, the following may prove to be useful in debugging this. First and foremost, the problem can be caused by the ClassLoader loading two copies of a particular class due to dependency overinclusion.
Supply the following option to your JVM via IDE or via
java -verbose:class {rest of your args / options}
Then, monitor the console output for the particular Parent class. A chance exists that the class has made it into the ClassLoader twice, perhaps by including a particular dependency more than once. Pay particular attention to the time when the bean is retrieved from lookup.
I was able to solve an issue on 4/22/2022 by using the above strategy to track down an issue in our Gradle build script that caused extra files to make their way into a WAR.
The Problem with your code is, that appContext.getBean("beanName") does not return an object that inherits from the class Parent.
A common mistake regarding classes with names like Parent is a wrong import.
Check if you are importing from the correct package.
If this does not fix the issue, make sure that appContext.getBean("beanName") returns the object you think it does.
It might return a Bean Object, that does not inherit from the Parent class.
The context also might not even contain your ChildBean object yet. Make sure it is added to it beforehand.
For example, in the model I have the object: Object (the table in the database is object), then the DAO class is ObjectDAO, but I have a base class named ObjectDAO too, which the another DAO classes extends, what name do you recommend to set?
I believe the name maybe BaseDAO
So, i really think that you may rename you entity class to another name to solve this conflict. But if you really need this, you can extend like this:
package entity;
public class BaseDAO{}// (your entity)
package dao;
public abstract BaseDAO<E extends Object> //(Your base dao)
Then in the dao for the entity BaseDAO:
package whatever; // not into the dao package ofcourse.
public class BaseDAO extends dao.BaseDAO<entity.BaseDAO> {} //
You need to inform the entire package name for all classes.
#Service
public interface DatabaseConnector {
public Model getModel();
}
#Configuration
#Profile({"!test"})
public class DatabaseConnectorT implements DatabaseConnector {
private final Model model;
#Autowired
public DatabaseConnectorT(#Value("${assemblerFile}") String assemblerFile) {
model = TDBFactory.assembleModel(assemblerFile);
}
}
I am getting the error, that this bean class cannot be instantiated and a default constructor should be given. Why should such one be required? I have two different implementations of the interface which should be loaded dependent on the active profile. Configuration should be done with annotations.
Default constructor is a constructor without parameters.
According to the error message I suppose that the class is being created via reflection.
So you must provide a way to create a class via reflection.
I assumed the value of assemblerFile in your constructor can't be determined via reflection and so the default constructor is called instead, which is not provided.
I know all the following rules of Java Interfaces:
You cannot instantiate an interface.
An interface does not contain any constructors.
All of the methods in an interface are abstract.
An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final.
An interface is not extended by a class; it is implemented by a class.
An interface can extend multiple interfaces.
Now my question is how we are creating an variable of interface EntityManager and using its methods like given code below:
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateful
public class Movies {
#PersistenceContext(unitName = "movie-unit")
private EntityManager em; // Here declaring a variable of an Interface
public void addMovie(Movie movie) throws Exception {
em.persist(movie); // Here using variable of an Interface to call its method
}
}
Please put some light on this so that I can clear up my understanding of how this code is working!
You're not creating anything here, the container is. All you've done is declare a dependency to be injected, this is how DI works in JavaEE. A very simplistic view of what is happening:
Your Movies EJB is proxied by the container
The proxy introspects your class and discovers the annotation you've declared, along with the field you've declared it on
The container provides an instance of the EntityManager to the proxy, which in turn makes it available to your implementation.
Presto: Instant EntityManager. Notice how little you're involved in the process?
The only thing you seem to be missing is the dependency injection. Here,
#PersistenceContext(unitName = "movie-unit")
private EntityManager em; // <-- this is an instance of a class that implements the
// EntityManager interface. Interfaces (as you note)
// cannot be directly instantiated.
The container uses field inspection and "sees" the #PersistenceContext(unitName = "movie-unit") annotation. It then injects the appropriate instance. Per the PersistenceContext Javadoc,
Expresses a dependency on a container-managed EntityManager and its associated persistence context.
The container manages it.
I've got a series of web actions I'm implementing in Seam to perform create, read, update, etc. operations. For my read/update/delete actions, I'd like to have individual action classes that all extend an abstract base class. I'd like to put the #Factory method in the abstract base class to retrieve the item that is to be acted upon. For example, I have this as the base class:
public abstract class BaseAction {
#In(required=false)#Out(required=false)
private MyItem item=null;
public MyItem getItem(){...}
public void setItem(...){...}
#Factory("item")
public void initItem(){...}
}
My subclasses would extend BaseAction, so that I don't have to repeat the logic to load the item that is to be viewed, deleted, updated, etc. However, when I start my application, Seam throws errors saying I have declared multiple #Factory's for the same object.
Is there any way around this? Is there any way to provide the #Factory in the base class without encoutnering these errors?
The problem you're encountering is that every Seam component needs a unique name - using your approach you'd have a component named "item" for each subclass.
I would do the following:
#Name( "action1" )
public class Action1 extends BaseAction
{
...
}
And in components.xml:
<factory name="action1Item" value="#{action1.item}" />