This is my eventAction ActionSupport Class
public class EventAction extends ActionSupport {
protected EventService eventService;
protected String redirectUrl;
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public void setEventService(EventService services) {
this.eventService = services;
}
}
And here is a fragment from my applicationContext.xml
<bean id ="eventService" class ="services.EventService" scope ="singleton">
<property name = "sessionFactory" ref = "sessionFactory"/>
</bean>
The code is working fine except for when I change the id inside the declartion.
My question why does spring <bean id ="eventService"> id has to be matched with eventService instance variable inside EventAction support class? isn't id is just making an identifier for the bean that is going to be created? why should the id inside the bean tag should be the same inside my EventAction, where the EventAction class is not even being mentioned in the configruation?
From Spring docs beans-beanname
Every bean has one or more ids (also called identifiers, or names; these terms refer to the same thing). These ids must be unique within the container the bean is hosted in. A bean will almost always have only one id, but if a bean has more than one id, the extra ones can essentially be considered aliases.
When using XML-based configuration metadata, you use the 'id' or 'name' attributes to specify the bean identifier(s). The 'id' attribute allows you to specify exactly one id, and as it is a real XML element ID attribute, the XML parser is able to do some extra validation when other elements reference the id; as such, it is the preferred way to specify a bean id. However, the XML specification does limit the characters which are legal in XML IDs. This is usually not a constraint, but if you have a need to use one of these special XML characters, or want to introduce other aliases to the bean, you may also or instead specify one or more bean ids, separated by a comma (,), semicolon (;), or whitespace in the 'name' attribute.
I believe for Spring-Struts2 you are using the plugin where you need to either define auto-wire strategy or plugin will use default one which is name.
That means when plugin bridge between Struts2 and Spring it will try to inject beans based on the supplied auto-wire strategy
Refer to Struts2 Spring-plugin
Related
I have the following bean that describes a mongo document, and that uses lombok:
#JsonDeserialize(builder = MyClass.MyClassBuilder.class)
#Builder(toBuilder = true)
#Value
public class MyClass {
private final String id;
#Default
private final String field = "defaultValue";
#JsonPOJOBuilder(withPrefix = "")
public static class MyClassBuilder {}
}
When deserializing {"id": "document"} with jackson, I end-up with a bean containing both id=document and field=defaultValue because it used the builder that provide a default value for the field.
Now what I want to do, is to have the defaultValue set for documents coming out of the database (coming from ReactiveMongoTemplate). But it seems to use the all args constructor even if I set it private (or some reflect black magic)
So the main question is: is it possible to tell spring to use the builder to build the bean when coming out of the database?
You are not going to be able to use your custom serialiser because when I go through the source code of MappingMongoConverter in spring mongodb (debugged it with a sample app) , I see only the following steps.
Once the value from db is available as org.bson.Document, MappingMongoConverter.java is looking to create your entity object.
First, it checks if you have any custom converters registered and if you have it, then use it. So one option is to use a custom converter registered.
If there is no custom converters registered, it goes and find the PersistenceConstructor and use it. I had an object with 3 constructors (no param, one param, and all param) and it chose my no param constructor.
However, if I annotate a constructor with #PersistenceConstructor, it is choosing that constructor. So could follow this approach but then you have to keep String field un-initialised and getting initialised differently in each constructor
MappingMongoConverter.java
conversions.hasCustomReadTarget
persistenceConstructor
I have a class MyBean with some fields including String "id".
I have a lot of xml-defined beans with IDs.
I want to fill "id" fields of MyBean java objects to xml-specified bean IDs. How to implement this without code duplicaton?
package just.artmmslv.example.MyBean
public class MyBean {
private String id;
private String foo;
//getters, setters, other fields
}
<beans xmlns="foobar+util">
<util:list value-type="just.artmmslv.example.MyBean">
<bean id="exampleBean01" class="just.artmmslv.example.MyBean">
<property name="foo" value="bar"/>
</bean>
<!--Other beans-->
</util:list>
</beans>
So, how to make exampleBean01`s field id to be equal to "exampleBean01" in convenient way?
Make id in MyBean of type String, not int (I see int in your code)
Make MyBean implements BeanNameAware
Implement method setBeanName in MyBean:
#Override
public void setBeanName(String s) {
this.id = s;
}
That's all you need
I think Spring provides a way to do this via BeanNameAware.
Read through: https://docs.spring.io/spring/docs/2.5.x/reference/beans.html#beans-factory-aware-beannameaware
Interface to be implemented by beans that want to be aware of their bean name in a bean factory. Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external
configuration, as well as a possibly unnecessary dependence on a Spring API.
I'm trying to initialize Spring bean with request scope, and lazy initialization from another object (attributes) that are not managed by Spring.
Here is the bean definition :
#Component
#Scope(value = "request")
#Lazy
public class LazyClass {
protected String name;
}
How do I init the 'name' attribute at runtime ?
It may not be the best solution but you can set the value of name into a System property and get it where you need it in your class.
Setting the value somewhere in a non-spring class:
// myProperty is the name of the property
// name is the value you want to store
System.setProperty("myProperty",name);
Getting inside your class:
// Caution: the name of the property must be the same as it was when it was set
String name = System.getProperty("myProperty);
The getting method can be called in the constructor of your bean class as it is marked as #Lazy.
EDIT:
Another way is to create a setter for the field name and set its value when you need it.
I'm implementing an in-memory API gateway to a SOAP service utilizing JAXB. One of the schema elements is a "choice", and there are several elements in the choice block.
I'm attempting to mirror the generated JAXB classes in the client namespace, so for this "choice" scenario I have a bean class with several properties, only one of which will be non-null.
I'm attempting to use the #NotNull annotation from javax.validation, along with the ValidatorFactory and Validator. However, a "choice" scenario makes this a little more complicated. I'm guessing this would call for a custom ConstraintValidator, along with a custom annotation to refer to the custom ConstraintValidator.
For instance, here's some fake code that resembles a part of my structure:
public class InquireRandomInformationRequest {
#NotNull(message ="subscriberSelector cannot be null")
#Valid
private SubscriberSelector subscriberSelector; // required
private SelectorMode mode; // optional
...
}
public class SubscriberSelector {
// Choice 1
private String billingAccountNumber; // \d{8,9,12,13}; required
private MarketInfo billingMarket; // optional
// Choice 2
private String subscriberNumber; // \d{10}; required
private ValidationCriteria validationCriteria; // optional
private BillingAccountInformation billingAccountInformation; // optional
private MemoProductType memoProductType; // optional
// Choice 3
private String unifiedBillingAccountNumber; // [0-9A-Za-z]{13}; required
...
}
I understand that I need the #Valid annotation on the "subscriberSelector" property for the validator to validate the sub-object. Past that, I'm not quite sure what I need to do to handle the choices problem.
To fit my example, I will need exactly one of "billingAccountNumber", "subscriberNumber", or "unifiedBillingAccountNumber" to be non-null (although I could compromise on simply taking the first non-null one in a particular sequence). In each "choice group", the other properties are optional, but it's possible that another property could be "required" if that particular choice group is selected (the selector property is non-null, in other words).
I've looked through the Hibernate Validator documentation, but I'm not sure exactly how to apply that for this situation.
If I define a custom annotation and a custom ConstraintValidator, where is the annotation referenced? On the class (like "SubscriberSelector") or on the "subscriberSelector" property (the former seems more logical to me).
You can define constraints on the class or on the property depending on your requirements.
Usually, the constraints are placed on the property but, in the case you mention, as multiple properties are concerned and interdependent, you should place the constraint at the class level.
See https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-declaring-bean-constraints in our documentation.
Problem:
How to save object Account as nested object when only ID is needed without getting ConstraintValidator exception?
Problem is because i have set validation rules to class, but when i want to save sem entity as nested object i get exception that some property values are missing. So i would liek to have different validation rules when i want to persist object as a whole and when i want to use it only sa nested object (when only ID is needed).
public class Account {
private int id;
#NotNull
private String name;
#NotNull
private String lastName;
#NotNull
private String userName;
//getters&setters
If I include Account as nested object i just need ID to be able to use it as FK (account entity is already in DB), but because of #NotNull annotation i get Exception.
Is there a way to ignore those annotations from Account when trying to save object Shop or how to create different validation rules for Account to validate just soem other properties and not all?
public class Shop {
private int id;
private Account owner; // only ID is needed
Do you have any basic example? I dont understand those in documentation. I have already read documentation before posting here.
You want to look at Bean Validation groups where you can classify specific validations so they are only activated when that group is validated and ignored otherwise.
You can refer to the documentation here for details.
Taking an example from the documentation:
// This is just a stub interface used for tagging validation criteria
public interface DriverChecks {
}
// The model
public class Driver {
#Min(value = 18, message = "You must be 18", groups = DriverChecks.class)
private int age;
// other stuffs
}
A group is nothing more than a tag that allows you to enable/disable validations based on specific use cases at run-time. By not specifying the groups attribute on a bean validation annotation, it defaults to the Default group, which is what Bean Validation uses if a group-tag isn't specified at the time of validation.
That means the following holds true:
// Age won't be validated since we didn't specify DriverChecks.class
validator.validate( driver );
// Age will be validated here because we specify DriverChecks.class
validator.validate( driver, DriverChecks.class );
This works great when you're triggering the validation yourself inside your service methods because you can manually control which group checks are applicable based on that method's use case.
When it comes to integrating directly with Hibernate ORM's event listeners that can also trigger bean validation, group specifications become a bit harder as they must be specified based on the event-type raised by hibernate.
javax.persistence.validation.group.pre-persist
javax.persistence.validation.group.pre-update
javax.persistence.validation.group.pre-remove
For each of the above properties you can specify in the JPA properties supplied to Hibernate, you can list a comma delimited list of groups that are to be validated for each of those event types. This allows you to have varying checks during insert versus update versus removal.
If that isn't sufficient, there is always the fact that you can create your own constraint validator implementation and annotation to plug into Bean Validation and specify that at the class or property level.
I have often found this useful in cases where values from multiple fields must be validated as a cohesive unit to imply their validity as the normal field-by-field validations didn't suffice.