Store Java enums in Postgresql and Hibernate 6 using hbm.xml - java

I am unable to figure out how to store a Java Enum using a Postgresql Enum Type with Hibernate 6 and the legacy hbm.xml.
With Hibernate 5, I used to use the hiberate-types project with following XML:
<property name="type" column="Type" access="field">
<type name="com.vladmihalcea.hibernate.type.basic.PostgreSQLEnumType">
<param name="enumClass">"my-java-enum-type"</param>
<param name="useNamed">true</param>
</type>
</property>
But, this is not working with Hibernate 6 anymore. There is a documentation from the package's Author how to use it with annotations, but currently it is not feasible for us to switch to annotations (https://vladmihalcea.com/the-best-way-to-map-an-enum-type-with-jpa-and-hibernate/).
I would be glad if anyone could give a hint.

I solved the issue by writing my own type:
public class PersistentEnum<T extends Enum<T>> extends EnumType<T>
{
#Override
public void
nullSafeSet(PreparedStatement preparedStatement, T obj, int index, SharedSessionContractImplementor session) throws HibernateException,
SQLException
{
if(obj == null)
{
preparedStatement.setNull(index, java.sql.Types.OTHER);
}
else
{
preparedStatement.setObject(index, obj.toString(), java.sql.Types.OTHER);
}
}
}
With this, the former posted hbm.xml code is working.

Related

Comma Separated List From Properties File As Constructor Argument in Spring Bean

I am trying to use below spring injection for list of strings.
<bean name="myBean" class="java.util.HashSet">
<constructor-arg type="java.util.Collection" value="#{'${my.list.of.strings}'.split(',')}"/>
</bean>
I am getting String "'${my.list.of.strings}'.split(',')" as constructor argument instead of List of Strings.
Is there any Version Issue?
I am using Spring Release 2.5, spring-beans 2.0.xsd
If your bean wasn't a HashSet and had a constructor that accepted an array as an argument, you could do something like this:
<bean name="myBean" class="mypackage.MyBeanClass">
<constructor-arg type="java.lang.String[]" value="${my.list.of.strings}" />
</bean>
Or this:
<bean name="myBean" class="mypackage.MyBeanClass">
<constructor-arg>
<value type="java.lang.String[]">${my.list.of.strings}</value>
</constructor-arg>
</bean>
(I don't remember which is the correct way for Spring 2.5, actually I don't remember if you can even use a placeholder. If this is the case, please consider using the last version of Spring, which by these days is 4.1.5.RELEASE).
But you want myBean bean to be of class HashSet. The only solution I can think of is to use your own class that wraps HashSet or maybe extends from it:
package mypackage;
// imports ommited
public class MyBeanClass extends HashSet<String> {
public MyBeanClass(String[] values) {
super(Arrays.asList(values));
}
}
If you don't like the idea to inherit directly from HashSet, then wrap it and make the wrapper delegate all the methods you want to it:
package mypackage;
// imports ommited
public class MyBeanClass implements Set<String> {
private final Set<String> delegate;
public MyBeanClass(String[] values) {
this.delegate = new HashSet(Arrays.asList(values));
}
public boolean add(String element) {
return this.delegate.add(element);
}
public boolean contains(Object element) {
return this.delegate.contains(element);
}
// TODO rest of delegate methods
}
The Spring Expression Language (spring-el) only appeared in Spring 3.0. Your expressions aren't going to be evaluated with Spring 2.5, you'll need to do that a different way.
Even with Spring 3, I'd recommend finding another way to build your set, such as using a FactoryBean (see Customizing instantiation logic using FactoryBeans)

Serialize a Tree of Java Objects into Custom XML

Imagine a tree of Java objects, i.e. a top level object of some class which contains some properties which in turn are objects of other classes and so on until we basically reach fundamental types like integer or string, etc. For example:
class Car {
private Door _leftDoor;
private Door _rightDoor;
}
class Door {
private String _name;
}
By serializing a top level object of class Car, I would like to see an XML document, for example, like this:
<object type="Car">
<property type="Door" identifier="_leftDoor">
<object type="Door">
<property type="String" identifier="_name">I am a left door!</property>
</object>
</property>
<property type="Door" identifier="_rightDoor">
<object type="Door">
<property type="String" identifier="_name">I am a right door!</property>
</object>
</property>
</object>
By the way, notice how this fragment could be plugged into some other hierarchy, for example, if Car object would be property of some other parent object.
My question is: what would be the right way to implement this patternwise, structurewise, designwise, architecturewise? I think my question needs some clarification. The first and simple way to implement this that comes to my mind is something similar to Java's conventional toString:
class Car {
...
public Element toElement(Element element) {
Document document = element.getOwnerDocument();
Attr attr;
Element objectElement = document.createElement("object");
element.appendChild(objectElement);
attr = document.createAttribute("type");
attr.setValue(class.getSimpleName());
objectElement.setAttributeNode(attr);
Element propertyElement;
propertyElement = document.createElement("property");
objectElement.appendChild(propertyElement);
attr = document.createAttribute("type");
attr.setValue(_leftDoor.getClass().getSimpleName());
propertyElement.setAttributeNode(attr);
attr = document.createAttribute("identifier");
attr.setValue("_leftDoor");
propertyElement.setAttributeNode(attr);
_leftDoor.toElement(propertyElement);
propertyElement = document.createElement("property");
objectElement.appendChild(propertyElement);
attr = document.createAttribute("type");
attr.setValue(_rightDoor.getClass().getSimpleName());
propertyElement.setAttributeNode(attr);
attr = document.createAttribute("identifier");
attr.setValue("_rightDoor");
propertyElement.setAttributeNode(attr);
_rightDoor.toElement(propertyElement);
return objectElement;
}
}
class Door {
...
public Element toElement(Element element) {
...
}
}
How good is this idea in the sense of adding this kind of XML serialization directly as methods of corresponding classes? Is it good that I've restricted it to have Element as parameter (although I'm kind of forced to do it because of the way Java XML API is designed)? Is it good that I return Element? Do you have any ideas what could be improved from the architectural point of view in this implementation? Any advice is welcome.
I'm aware of the java.beans.XMLEncoder facility, but this is Java specific XML serializer and redundant for me in this case.
Why not use something like XStream? If that's not applicable then I would suggest you use the reflection API to allow you to keep the code that generates the XML separate. Perhaps you could write a generic method using reflection that would do the job rather than writing specific XML serialization code for each class. You could use custom annotations to specify more granular behaviour within your classes if necessary. But it feels like re-inventing the wheel because something like XStream can probably do a lot of that for you.

Spring - set a property only if the value is not null

When using Spring, is it possible to set a property only if the value passed is not null?
Example:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param}"/>
</bean>
The behavior I'm looking for is:
some.Type myBean = new some.Type();
if (${some.param} != null) myBean.setAbc(${some.param});
The reason I need this is since abc has a default value which I don't want to override with a null.
And the Bean I am creating is not under my source control - so I cannot change its behavior. (Also, abc for this purpose might be a primitive, so I can't set it with a null anyway.
EDIT:
According to the answers I think my question requires clarification.
I have bean I need to instantiate and pass to 3rd party I use. This bean has many properties (12 currently) of various types (int, boolean, String, etc.)
Each property has a default value - I don't know what it is and would prefer not needing to know unless it becomes an issue.
What I'm looking for is a generic solution that comes from Spring's abilities - currently the only solution I have is a reflection based.
Configuration
<bean id="myBean" class="some.TypeWrapper">
<property name="properties">
<map>
<entry key="abc" value="${some.value}"/>
<entry key="xyz" value="${some.other.value}"/>
...
</map>
</property>
</bean>
Code
public class TypeWrapper
{
private Type innerBean;
public TypeWrapper()
{
this.innerBean = new Type();
}
public void setProperties(Map<String,String> properties)
{
if (properties != null)
{
for (Entry<String, Object> entry : properties.entrySet())
{
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
setValue(propertyName, propertyValue);
}
}
}
private void setValue(String propertyName, Object propertyValue)
{
if (propertyValue != null)
{
Method method = getSetter(propertyName);
Object value = convertToValue(propertyValue, method.getParameterTypes()[0]);
method.invoke(innerBean, value);
}
}
private Method getSetter(String propertyName)
{
// Assume a valid bean, add a "set" at the beginning and toUpper the 1st character.
// Scan the list of methods for a method with the same name, assume it is a "valid setter" (i.e. single argument)
...
}
private Object convertToValue(String valueAsString, Class type)
{
// Check the type for all supported types and convert accordingly
if (type.equals(Integer.TYPE))
{
...
}
else if (type.equals(Integer.TYPE))
{
...
}
...
}
}
The real "difficulty" is in implementing convertToValue for all possible value types.
I have done this more than once in my life - so it is not a major issue to implement it for all possible types that I need (mostly primitives and a few enums) - but I hoped a more intelligent solution existed.
You can use SpEL and placeholder and default value for placeholder mechanisms together as following:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param:#{null}}"/>
</bean>
For solve your problem, you have to use SEL(Spring Expression Language).
By this feature (added in SPring 3.0) you can such as other dynamic language writing your condition. For your context, answer is:
<bean name="myBean" class="some.Type">
<property name="abc" value="#(if(${some.param} != null) ${some.param})"/>
</bean>
for more information see(this tutorial says what use SEL in context file):
http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html
You can use default value concept in property configurer in Spring framework as following:
<bean name="myBean" class="some.Type">
<property name="abc" value="${some.param : your-default-value}"/>
</bean>
you can set default value by this approach. By this context config if some.param key exist so its value set in abc property and if don't exist your-default-value set in abc property.
Note: Another benefit of this approah is:"In POJO programming model better approzh is member of class don't have any default value,and default value injected from out of class."
You can create a Utility class that will act as a Factory class for some.Type, and wrap the logic there
For Example :
public class TypeFactory {
public static Type craeteType(SomeType param){
Type t = new Type();
if(param!=null)
t.setParam(param);
}
}
and on XML configure the bean creation using this Factory method
<bean id="myBean" class="some.Type"
factory-method="craeteType">
<constructor-arg ref="param"/>
</bean>
This looks like a job for Java-based container configuration. You'll be able to do what you do in your XML config, but with all the power of Java.
I've got it working with following snippet:
<bean name="myBean" class="some.Type">
<property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" />
</bean>

lazy fetching problem

I have a problem with lazy fetching. here's what I have. I have a entity class called channel. and another entity class called show. Each channel has many show's. I've implemented hibernate with lazy fetching.But heres the problem, when I get a channel from database and after that try to access the programm list I get a nullpointerException.
Here's some code:
telekanalService.findAllTelekanal(new AsyncCallback<List<Telekanal>>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
errorLabel.setText(caught.getMessage());
}
public void onSuccess(List<Telekanal> result) {
//Programm tel = result.get(1);
List<Programm> prog = result.get(0).getProgrammid(); //problem with this
//Telekanal tell = tel.getTelekanal();
errorLabel.setText("tehtud:" + prog.size()); //returns Nullpointerexception
}
});
Maybe I have some mapping errors, here are my mapping files
Programm.hbm.xml:http://pastebin.com/Q639HreT
Telekanal.hbm.xml: http://pastebin.com/4c3h0fZj
Programm class:http://pastebin.com/ws57uGg2
Telekanal class:http://pastebin.com/MZB7KgT1
Or maybe I have problem in my sql setup: http://pastebin.com/AVBM8882
And also I'm using opensessioninview for keeping the session open
My code
Really hope that someone can help
<list name="programmid" inverse="false" table="programm" lazy="true">
<key>
<column name="t_id" />
</key>
<list-index></list-index>
<one-to-many class="com.tvkava.shared.model.Programm" />
</list>
Shouldn't declaring an empty list-index cause an error? I'm not sure how this would work.

JiBX: How do I keep using interfaces in my code?

How can I keep my using interfaces in classes I want to use JiBX binding with?
Example:
I have this very simple model in java:
public interface A {
B getB();
void setB(B b);
}
public interface B {
String getData();
void setData(String data);
}
public class AImpl implements A {
B b;
#Override
public B getB() {
return b;
}
#Override
public void setB(B b) {
this.b = b;
}
}
public class BImpl implements B {
private String data;
#Override
public String getData() {
return data;
}
#Override
public void setData(String data) {
this.data = data;
}
}
And this binding document:
<binding>
<mapping name="A"
class="com.test.AImpl">
<structure name="B" usage="optional" get-method="getB" set-method="setB"/>
</mapping>
<mapping name="B"
class="com.test.BImpl">
<value name="data" set-method="setData" get-method="getData" usage="optional"/>
</mapping>
</binding>
When I try to run my code I get this exception:
java.lang.ClassFormatError: Method
in class com/test/B has illegal
modifiers: 0x1001
I've tried to use 'abstract="true"' on both mapping, only to get this exception:
...Caused by:
org.jibx.runtime.JiBXException: Unable
to access binding information for
class com.test.A Make sure the binding
has been compiled...
The only solution I've found is to have AImpl hold a BImpl instead of a B, and have the getter return BImpl and the setter recieve BImpl. This is very wrong as it breaks the interface completely.
How can I solve this? I've been pulling hairs out, having tantrums (the real issue is much more complex, and JiBX cryptic error messages don't help) - nothing help.
Is this solvable? Is JiBX really that intrusive (in that it requires me to abandon all interface programming?)
Please don't answer "use AbstractB" as it's the same problem, only one level removed.
In the mapping, you should be able use the "create-type" attribute to specify the concrete class that JiBX should instantiate for bean properties that have an interface type. I use this a lot for collection properties. For example, you can tell JiBX to instantiate a java.util.HashSet for a property of type java.util.Set. But I believe it works just as well for non-collection properties. Your mapping would look something like:
<mapping class="com.mypackage.AImpl" name="A">
<structure get-method="getB" set-method="setB" create-type="com.mypackage.BImpl">
...
</structure>
...
</mapping>
JiBX will call the no-arg constructor to create the B object. Alternatively, you could use a factory or a custom serializer/deserializer if you need fancy instantiation logic. See this reference page for details.
Another good resource is the binding.dtd - apparently it's not in the distribution but can be downloaded from here: http://jibx.cvs.sourceforge.net/viewvc/checkout/jibx/core/docs/binding.dtd. Put this file somewhere (c:\binding.dtd for example). Then, in the top binding entry, use this:
<binding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file://jibx/binding.dtd">
and register file://jibx/binding.dtd to point to your saved binding.dtd for documentation and verification goodies.
It's amazing what inertia does - I know that xml files should have schemas / dtds, I've used them before and always said "without a schema understanding this would've been impossible". Yet when I've entered this project, it never occurred to me to search for the schema / dtd for this xml - I just accepted it as given that it had none.
Lesson learned.

Categories