вторник, 30 августа 2016 г.

BeanCurrentlyInCreationException due to bug in spring boot

Run into a problem:
If project is built on Windows machine, it works perfectly.
If project is built on TeamCity CI Linux-agent, than on application startup I get the following exception:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'someBeanName': Requested bean is currently in creation: Is there an unresolvable circular reference?

It turned out that there is a bug in spring boot, which leads to this error - if using @ComponentScan on a large scope (e.g. main package of the project).

I had a @SpringBootApplication annotation on my main spring boot class, which also includes the @ComponentScan. Bug was gone after overriding it with specifying concrete packages:

@ComponentScan({"ru.thecop.config",
        "ru.thecop.service",
        "ru.thecop.controller"})

It seems that the order of packages in this annotation is important - if you still experiencing problems with startup/bean creations, a possible solution is to change order of packages in @ComponentScan.

Additional info on this problem can be found on Spring Boot Github and Jira Ticket.

среда, 17 августа 2016 г.

Non-compatible bean instance of type $Proxy123

Situation: I have a @Configuration class, with a @Bean method, which return type is a concrete class, not an interface. And this class is @Transactional.
Ran into an exception:

java.lang.IllegalStateException: @Bean method SomeConfig.beanCreateMethod called as a bean reference for type [com.example.BeanType] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy123]. Overriding bean of same name declared in: com.example.SomeConfig

According to this thread (it is old even now; but still useful):

The problem is that you use spring aop at your application (either directly or indirectly via using spring transactions).

Spring aop is proxy-based. It uses jdk proxies by default.

Jdk proxies can be casted only to the target interfaces. If you try to cast a proxy to the concrete class you get ClassCastException.

Bean named 'timedUserSync' is processed by spring aop and every time you try to use it at the application, you use jdk proxy instead. That produces the problem when the framework tries to use the bean as an object of concrete class.

Solution is to setup cglib usage for your aop infrastructure - set 'proxy-target-class="true''' for all used <aop:config>, <aop:aspectj-autoproxy> or <tx:annotation-driven> elements. Also you must be sure that cglib binaries are available at classpath.

Corresponding reference sections:
So adding proxyTargetClass = true to the @EnableTransactionManagement annotation solved the problem.

вторник, 16 августа 2016 г.

Strange: autowiring and spring boot resource reading

Strange things:
1. Spring bean autowiring might not work as expected, the beans your bean depends on are not instantinated and turn out to be null. As in this case:
@Autowired
private SomeBean someBean;

@Bean
public OtherBean otherBean() {
    OtherBean b = new OtherBean();
 b.setSome(someBean); // someBean here can be null!
    return b;
} 

So you can try to pass the someBean through parameter, this worked for me once:

@Bean
public OtherBean otherBean(SomeBean someBean) {
    OtherBean b = new OtherBean();
 b.setSome(someBean); // someBean will be instantinated
    return b;
}

2. If you want to read some resource from spring boot jar, you may run into FileNotFoundException, even if actually file will be on the specified path. Reading the resource as InputStream should help:

try (BufferedReader buffer = new BufferedReader(
new InputStreamReader(cpr.getInputStream()))) 
{
    List<String> lines = buffer.lines().collect(Collectors.toList());
    lines.forEach(System.out::println);
}

воскресенье, 15 мая 2016 г.

Hibernate single-table hierarchy with abstract superclass and referencing it

Suppose you want a hierarchy of some entities that have common superclass, for example, a company's facilities. And there are several requirements:

1. The hierarchy is stored in single table
2. Hierarchy is made of different classes and we want to know their types when go through it.
3. Classes may or may not contain fields that are related to certain level of the hierarchy
4. Reference to the parent entity is stored in "parent_id" column regardless of current hierarchy level, class name, parent, etc.
5. The employee class has a reference to the AbstractFacility class, so "An Employee can work at facility of any level of hierarchy".
6. We can define the actual type of AbstractFacility the employee has reference to.

Let's take a look at the code:
@Entity
@Table(name = "facility")
@DiscriminatorColumn(name = "facility_type")
public abstract class AbstractFacility {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    protected String name;
}

@Entity
public class GlobalHQ extends AbstractFacility {
//The GlobalHQ is the highest in the hierarchy, has no parent
    @OneToMany(mappedBy = "globalHq", cascade = CascadeType.ALL)
    private List<LocalHQ> localHqs;
}

@Entity
public class LocalHQ extends AbstractFacility {
    @NotNull
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private GlobalHQ globalHq;

    @OneToMany(mappedBy = "localHq", cascade = CascadeType.ALL)
    private List<LocalShop> localShops;
}

@Entity
@SecondaryTable(name = "shop_secondary", pkJoinColumns = @PrimaryKeyJoinColumn(name = "shop_id"))
public class LocalShop extends AbstractFacility {
    @NotNull
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private LocalHQ localHq;

    //This field belongs only to LocalShop class
    @Column(table = "well_secondary")
    private String shopData;

}
As you can see, all facilities are descendants of a AbstractFacility, and GlobalHQ has many localHqs, each LocalHQ has many LocalShops.
LocalShop class has a field "shopData" that must not be contained in the main hierarchy table. The example contains only one such field, but in real case there can be a lots of them in any level of the hierarchy, and it's a bad idea to store them in the same common table, it will be a mess of columns. So, we use a secondary table to store additional fields there.

Let's take a look at the employee class, it's first, flawed version:
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    private AbstractFacility workPlace;
}
At first glance this class seems to be ok, and it almost is: hibernate will map the workpalce field. The problem will occur when we try to determine the subclass of the workPlace: using the instanceof will cause the exception. That is because the hibernate does not know the exact subclass of the AbstractFacility, and debugger will show you that the class of the workplace field is "AbstractFacility", and it can not be cast to any of the subclasses. This can be quite a surprise, because you could expect the hibernate to define the subclass of AbstractFacility by the discriminator column, but it does not.

The solution is to use the hibernate's @Any annotation, which will force the Employee class to store the actual type of workplace field in a separate column:
@Entity
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Any(metaColumn = @Column(name = "workplace_type"))
    @AnyMetaDef(idType = "long", metaType = "string",
            metaValues = {
                    @MetaValue(targetEntity = GlobalHQ.class, value = "GlobalHQ"),
                    @MetaValue(targetEntity = LocalHQ.class, value = "LocalHQ"),
                    @MetaValue(targetEntity = LocalShop.class, value = "LocalShop")
            })
    @ManyToOne
    private AbstractFacility workPlace;
}
Using this annotation hibernate will map the actual subclass, so you can use the instanceof and class-casts without exceptions.

The drawback of this solution appears when you add a new class to your hierarchy - you must remember to add a metaValue to all classes that refer to AbstractFacility using @Any.

четверг, 28 апреля 2016 г.

How to highlight syntax in your blog

First of all, go to higlighter's developer page.

Go to your blog template settings, and choose to edit HTML.
Than paste following code before </head> tag (note, you must supply additional shBrush* files for additional languages):

<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
Paste the following code before </body> tag.
<script type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script> 
Save the template. Now use it:
<pre class="brush: html">
...Your html-escaped code goes here...
</pre>
Remember that you have to escape your HTML characters.