문제

Using Hibernate 3.6.8.Final and Spring 3.0.5.RELEASE , I'm trying to add some Common DAO functionality for classes that have multiple implementations overridden higher up to implement the specific classes however it doesn't work for DetachedCriteria.

Example:

In base class:

public interface ICat {
    public void setMeowSound(String meow);
    public String getMeowSound();
}

Then each inherited project would define the hibernate annotations.

e.g.

@Entity
@Table(name="SQUAWKY_CATS")
public class SquawkyMeowingCat implements ICat, Serializable {
    @Id
    @Column(name="SQUAWK_NAME")
    private String meow;

    public String getMeowSound() {
        return meow;
    }

    public void setMeowString(String meow) {
        this.meow = meow;
    }
}

This means I can use:

Criteria criteria = Session.createCriteria(ICat.class);

And Spring/Hibernate knows that it pulls the annotations for ICat from the concrete inheritance in the particular project.

However if I try to do:

DetachedCriteria subQuery = DetachedCriteria.forClass(ICat.class,"inner"); // etcetera

then I get an Unknown entity at runtime for ICat.

Now this makes sense as in the first instance is creating it off the Session so it has all the configuration that it needs whereas the DetachedCriteria is a static method however it errors when trying to do the

criteria.list()

by which time it has picked up the Session and should know that ICat is actually a SquawkyMeowingCat which has all the annotations.

So my questions are two part:

1) Is this known behaviour and will be like this forever more?

2) Can anyone think of a simple way around it without using an Interface and concrete ClassHolder which hands back the instance of the class it needs to create?

도움이 되었습니까?

해결책

I'm not sure about the case of the DetachedCriteria, but one way to avoid explicit dependence on the concrete class might be to query Hibernate's metadata using the interface:

public <T> Class<? extends T> findEntityClassForEntityInterface(
    SessionFactory sessionFactory, 
    Class<T> entityInterface
) {
    for (ClassMetadata metadata : sessionFactory.getAllClassMetadata().values()) {
        Class entityClass = metadata.getMappedClass(EntityMode.POJO);
        if (entityInterface.isAssignableFrom(entityClass)) {
            return entityClass;
        }
    }
    return null;
}

With the usual caveats about the robustness of illustrative code spippets.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top