Below error is seen on my eclipse. I am just trying to save a terminalgroup object and was getting an error about TerminalGroupImpl not found. So I created a TerminalGroupImpl.java to be a hibernate file that has the #Entity for the terminal_group table. I have a TerminalGroupDaoHibernate.java file that using the TerminalGroupImpl.class to execute queries on the terminal_group table.
Please if someone can tell me what is wrong with my code and/or what I can do to figure out what is wrong?
Error
Invalid property 'terminalGroupDaoHibernate' of bean class
[com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupServiceImpl]:
Bean property 'terminalGroupDaoHibernate' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
Here is my applicationContext.xml file:
<!-- Terminal Group Service -->
<bean id="com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupService"
class="com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupServiceImpl">
<property name="terminalGroupDao"
ref="com.ccadllc.dac.model.consumer.terminalgroups.dao.TerminalGroupDao"/>
<property name="terminalGroupComponentDao"
ref="com.ccadllc.dac.model.consumer.terminalgroups.dao.TerminalGroupComponentDao"/>
</bean>
<bean id="com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupImpl"
class="com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupImpl" abstract="true">
<property name="terminalGroupDaoHibernate"
ref="com.ccadllc.dac.model.consumer.terminalgroups.dao.TerminalGroupDaoHibernate"/>
</bean>
<bean id="com.ccadllc.dac.model.consumer.terminalgroups.dao.TerminalGroupDao"
class="com.ccadllc.dac.model.consumer.terminalgroups.dao.TerminalGroupDaoHibernate">
<property name="messageService" ref="com.ccadllc.dac.messaging.MessagingService" />
</bean>
under hibernate.annotated.classes:
<value>com.ccadllc.dac.model.consumer.terminalgroups.TerminalGroupImpl</value>
TerminalGroupServiceImpl.java
Getter/Setter in TerminalGroupServiceImpl.java:
private TerminalGroupDao terminalGroupHibernateDao;
/**
* #param TerminalGroupHibernateDao The TerminalGroupHibernateDao to set.
*/
#Required
#Transactional
public void setTerminalGroupHibernateDao(final TerminalGroupDao terminalGroupHibernateDao)
{
this.terminalGroupHibernateDao = terminalGroupHibernateDao;
}
#Required
#Transactional
public TerminalGroupDao getTerminalGroupHibernateDao()
{
return terminalGroupHibernateDao;
}
You are trying to set terminalGroupDaoHibernate property instead of terminalGroupHibernateDao.
The property you have defined in the xml is "terminalGroupDaoHibernate", but the setter in your service impl's name is "setTerminalGroupHibernateDao". There is typo error. The setter name should be "setTerminalGroupDaoHibernate"
You should not add the #Required annotation on a getter. Also, in your bean xml, you use the property name terminalGroupDao but your setter has the name setTerminalGroupHibernateDao rather than setTerminalGroupDao.
Related
Sorry for the copy of this article. I'd want to comment it, but without 50 scores of reputation I can`t comment, so...
I have
private boolean stopLoggingIntoDb;
....
public void setStopLoggingIntoDb(String stopLoggingIntoDb) {
this.stopLoggingIntoDb = BooleanUtils.toBoolean(stopLoggingIntoDb.replaceAll("[^A-Za-z]", ""));
logger.warn("Logging into SiebelMethodLogs is " + (!this.stopLoggingIntoDb ? "ON" : "OFF"));
}
and XML
<bean id="siebelMethodProcessor" class="com.entities.utils.Logger">
<property name="logService" ref="logService"/>
<property name="stopLoggingIntoDb" value="${monitor.siebel.stopLogging}"/>
</bean>
In that case, is everything Ok, but If I change the property in setter method from stopLoggingIntoDb to stopLog and change the property name in XML also to stopLog or not, Spring said me Invalid property 'stopLoggingIntoDb' or Bean property 'stopLog' is not writable.
Because of that, my question is What the Spring does with setter method? Which value is injected and which field/property is searching while gets the injection?
As can be seen in this example in the Spring Documentation, the name attribute of the <property> element must match a setter method. The name of the methods parameter and the name of the field doesn't matter.
Examples of dependency injection
The following example uses XML-based configuration metadata for setter-based DI. A small part of a Spring XML configuration file specifies some bean definitions:
<bean id="exampleBean" class="examples.ExampleBean">
<!-- setter injection using the nested ref element -->
<property name="beanOne">
<ref bean="anotherExampleBean"/>
</property>
<!-- setter injection using the neater ref attribute -->
<property name="beanTwo" ref="yetAnotherBean"/>
<property name="integerProperty" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean {
private AnotherBean beanOne;
private YetAnotherBean beanTwo;
private int i;
public void setBeanOne(AnotherBean beanOne) {
this.beanOne = beanOne;
}
public void setBeanTwo(YetAnotherBean beanTwo) {
this.beanTwo = beanTwo;
}
public void setIntegerProperty(int i) {
this.i = i;
}
}
Notice how name="integerProperty" matches up to the setIntegerProperty() method, even though the parameter is named i and the field is named i.
I’m trying to understand a piece of Spring code that I need to adapt.
I have:
<bean id="…" class="…">
<property name="expr"
value="teams.contains(member.team) and not empty(member.projects)" />
</bean>
The corresponding class has a field
private Expression expr;
of type
org.apache.commons.jexl2.Expression
Now I am trying to find the appropriate Spring annotation to get rid of the XML file. But I cannot even understand how a simple String property can be injected as a jexl2.Expression object. How does this work?
A friend found the answer:
There was another XML file with this:
<bean id="bean_for_ExprConverter" class="package.of.custom.ExpressionConverter">
<constructor-arg ref="bean_for_JexlEngine"/>
</bean>
and also, in the project’s properties:
application.spring.converters = #{{\
#'bean_for_ExprConverter'\
}}
Thus, as long as the converter bean is defined, it should be enough to simply inject the expression string with the #Value annotation.
This is a Spring Hibernate implementation. I have defined a custom Type definition where I need to pass
one default value to my custom Type Definition class as below.
But the value is null please help me what am I missing here ?
#TypeDef(name = "customString", typeClass = com.mydomain.EncryptString.class)
public class employee{
private String empId;
private String empName;
#Type(type="customString")
private String passportNumber;
//setter and getters
}
public class EncryptString mplements UserType{
private String password; // inject via spring configurations
#Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
String encryptedPassport = rs.getString(names[0]);
System.out.println(names.length);
System.out.println("##"+password); // This null ????
return ""
}
//password getters and setters methods
}
Spring configurations
<bean id="customString"
class="com.mydomain.EncryptString">
<property name="password" value="password" />
</bean>
value of the password password in nullSafeGet() method it prints Null. How to make it
inject ? I expect Spring will load all the given default values and it instantiate values
when the EncryptString class call via Hibernate annotation.
Updating my question with findings
I have saw a example where TypeDef pass spring bean id as a parameter as below.
#TypeDef(name = "encryptedString", typeClass =
org.jasypt.hibernate.type.EncryptedStringType.class, parameters = { #Parameter(name
= "encryptorRegisteredName", value = "hibernateStringEncryptor") })
Spring configuration is
<bean id="hibernateStringEncryptor"
class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor">
<property name="registeredName" value="hibernateStringEncryptor" />
<property name="password" value="password" />
<property name="saltGenerator">
<bean class="org.jasypt.salt.FixedStringSaltGenerator">
<property name="salt" value="salt"/>
</bean>
</property>
hibernateStringEncryptor configuration is injected via type def passing the bean id as a
parameter. I went through the code http://www.jasypt.org/download.html but could not figure
out the way the bean get injected.
I think you need to use #Configurable annotation because Spring doesn't instantiate the custom types, Hibernate does and Spring doesn't know about those instances. This is the section in the documentation that describes the scenario. I haven't used this approach myself, but #Configurable would be the first thing I'd try.
Basically, you need to annotate your EncryptString class with #Configurable, to add spring-aspect.jar to your project's classpath, to add <context:spring-configured/> to your xml config file and to enable AspectJ weaving. The documentation gives quite some details regarding this.
In all the examples of autowiring that I have found, the example is about one <bean> autowire attribute which is set for example to byName, and the has only one property value which is supposed to be set through autowiring.
My question is what if a <bean> has multiple properties that you want to set through autowiring? No one seems to explain that situation. Can someone explain if I can or if I should use autowire to set multiple properties in a bean? The following is an example of such a situation where I want to set the account and credit properties of the customer bean by autowiring:
<beans>
<bean name="customer" class="ultratech.com.Customer" autowire="byName">
<bean name="account"/>
<bean name="credit>
</beam>
<bean name="account" class="ultratech.com.Account"/>
<bean name="credit" class="ultratech.com.Credit"/>
</beans>
Also, please correct me if I'm wrong, but if I were to use annotation (#Autowire), then my problem is easily solved, since I would be able to add #Autowire to any property of a bean separately.
[EDIT: edited to reflect on updated question]
Your question is much more clear right now. You seem to think (if I follow your thinking properly), that in the autowire="byName" you are supposed to provide a bean name instead of byName value.
That is not correct. The autowire attribute can take a few possible values and byName is one of those. When you set autowire to byName like here:
<bean name="someBean" class="foo.bar.Baz" autowire="byName />
then Spring will look at all the fields in someBean (foo.bar.Baz class) and attempt to wire all fields of this object on a per name basis. That is, (in your case) if a Customer class has a field account, Spring will look in its context and try to find a bean with name account to inject into the Customer bean.
If you define two such beans:
<bean name="customer" class="ultratech.com.Customer" autowire="byName" />
<bean name="account" class="ultratech.com.Account" />
then you are good to, if Customer is a class along this lines:
public class Customer {
(...)
private Account account;
(...)
}
Here is what your XML code snippet should look like, assuming that your Customer class has fields named account and credit:
<beans>
<bean name="customer" class="ultratech.com.Customer" autowire="byName" />
<bean name="account" class="ultratech.com.Account" />
<bean name="credit" class="ultratech.com.Credit" />
</beans>
Apart from "byName" autowiring, you can autowire:
no - default - no autowiring
byType - looks for a bean of the property type - be wary, though - only one bean of this type is allowed for autowiring byType; if there is more then one an exception is raised
constructor - works just like byType, but looks for constructor parameters only; all of constructor parameters have to be satisfied with exactly one bean of each respective type
See Spring reference for more info:
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-factory-autowire
I'm getting an error when passing an integer through spring.
<bean id="propConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/application.properties"/>
</bean>
<bean id="portListenerService" class="com.service.portListenerService" scope="prototype" lazy-init="true" parent="abstractService">
<property name="devicePort" value="${devicePort}"/>
</bean>
portListenerService.java:
#Required
public final void setDevicePort(Integer devicePort) {
this.devicePort= devicePort;
}
Is this the correct way to do this? Because I am getting an error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'portListenerService' defined in ServletContext resource [/WEB-INF/service-config.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [int] for property 'devicePort'; nested exception is java.lang.IllegalArgumentException: Original must not be null
Even when I hardcode the port instead of pulling it from application.properties, I get the same error. Is some other problem amiss?
Could the devicePort related code be violating javabean spec - like in this discussion?
It may not have anything to do with type of field. Usually this happens when there is a problem with setters, make sure the setter exists with return type void and your fields must start with lower case letter and setter would obviously have camel case for property with 'set' as prefix.
for example; I had the same issue recently and find out that the one of the letter within the property had different case in setter.
<bean name="gateway" class="com.xxxx.yyyy.zzz.MyClass" init-method="init">
...
<property name="stateLogIntervalms" value="${mux.state.log.interval.ms}" />
...
</bean>
definition of property in my class for correct like following;
protected Long stateLogIntervalms;
However definition of setter for incorrect like this;
public void setStateLogIntervalMs(Long stateLogIntervalms) {
this.stateLogIntervalms = stateLogIntervalms;
}
you can notice that the second last letter 'M' is in different case than what I had in xml property and java class.
Happy Coding:)