Ошибка “Дублирующего метода” при использовании Hibernate + Javassist + Gilead

StackOverflow https://stackoverflow.com/questions/2269185

Вопрос

Мое веб-приложение использует GWT 2.0.2, GXT 2.1.1, Hibernate 3.5-CR1, Javassist 3.11.0 и Gilead 1.3.1 (последняя версия от SVN).

Мое приложение работало просто отлично с GWT 1.7.1 + Gilead 1.2.

Я хочу воспользоваться некоторыми возможностями GWT 2.0 и решил, что в процессе обновлюсь до последней версии Gilead.Я указал на новый файл gwt.xml в Gilead 1.3.Я также использую новый net.sf.gilead.pojo.gwt.LightEntity вместо net.sf.gilead.pojo.java5.LightEntity.

У меня есть несколько спящих объектов / классов, которые расширяют Легкость (т.е.Вопрос, Форма), а также еще несколько сущностей / классов, которые расширяют сущность Вопроса.Не уверен, имеет ли это значение, но я использую InheritanceType.ПРИСОЕДИНИЛСЯ для стратегии наследования в объекте вопроса.

Для справки, вот класс вопросов:

@Entity
@Table(name = "Questions")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Question extends LightEntity implements IsSerializable,
        IFormItem, Comparable<Question> {

    private static final long serialVersionUID = 9180458948973980161L;

    public static final String FIELD_NAME_PREFIX = "field_"; //$NON-NLS-1$

    private static final String REQUIRED_QUESTION = "<span style=\"color: red;\">*</span>"; //$NON-NLS-1$

    public static int MIN_WIDTH = 50;
    public static int DEFAULT_WIDTH = 200;
    public static int MAX_WIDTH = 600;

    private int id;
    private Integer questionOrder;
    private String questionNumber;
    protected String questionText;
    protected boolean required;
    private String toolTip;
    protected Integer fieldWidth;

    @Id
    @GeneratedValue
    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isRequired() {
        return this.required;
    }

    public void setRequired(boolean required) {
        this.required = required;
    }

    public String getToolTip() {
        return this.toolTip;
    }

    public void setToolTip(String toolTip) {
        this.toolTip = toolTip;
    }

    @Column(length = 5000)
    @Lob
    public String getQuestionText() {
        return this.questionText;
    }

    public void setQuestionText(String pText) {
        this.questionText = pText;
    }

    public Integer getQuestionOrder() {
        return this.questionOrder;
    }

    public void setQuestionOrder(Integer questionOrder) {
        this.questionOrder = questionOrder;
    }

    public String getQuestionNumber() {
        return this.questionNumber;
    }

    public void setQuestionNumber(String questionNumber) {
        this.questionNumber = questionNumber;
    }

    public boolean hasQuestionNumber() {
        return getQuestionNumber() != null
                && !getQuestionNumber().trim().isEmpty();
    }

    public Integer getFieldWidth() {
        return this.fieldWidth;
    }

    public void setFieldWidth(Integer fieldWidth) {
        this.fieldWidth = fieldWidth;
    }

    public Component render(FormPanel formPanel, int order, int questionSpacing) {
        final Component c = generateWidget(getId());
        if (c instanceof Field<?>) {
            final Field<?> field = (Field<?>) c;
            field.setLabelSeparator(FormBuilderConstants.EMPTY_TEXT);
            field.setValidateOnBlur(true);
            field.setAutoValidate(true);
            field.setName(FIELD_NAME_PREFIX.concat(String.valueOf(getId())));
            if (getToolTip() != null) {
                field.setToolTip(getToolTip());
            }

            final FormData formData;
            if (field instanceof SimpleComboBox<?>) {
                formData = new FormData();
            } else {
                if (getFieldWidth() == null) {
                    field.setAutoWidth(true);
                    formData = new FormData(FormBuilderConstants.FORM_ANCHOR_SPEC);
                } else {
                    field.setWidth(getFieldWidth().intValue());
                    field.setAutoWidth(false);

                    formData = new FormData(getFieldWidth().intValue(), -1);
                }
            }

            final String questionNumber;
            if (this.questionNumber != null && !this.questionNumber.isEmpty()) {
                questionNumber = this.questionNumber;
            } else {
                questionNumber = String.valueOf(order);
            }

            if (this.answerable()) {
                String displayQuestionText = questionNumber.concat(". ") //$NON-NLS-1$
                        .concat(getQuestionText());
                if (isRequired()) {
                    displayQuestionText = displayQuestionText
                            .concat(REQUIRED_QUESTION);
                }

                field.setFieldLabel(displayQuestionText);
            }

            field.setIntStyleAttribute("margin-bottom", questionSpacing); //$NON-NLS-1$

            formPanel.add(field, formData);
        } else {
            formPanel.add(c);
        }

        return c;
    }

    protected abstract Component generateWidget(final int id);

    public abstract String questionType();

    public int compareTo(final Question q) {
        return this.questionOrder.intValue() - q.questionOrder.intValue();
    }

    public boolean answerable() {
        return true;
    }
}

В моем приложении есть сервлет запуска, который создает фабрику сеансов гибернации.В журналах я получаю ошибку "дублирующий метод" для всех классов, которые прямо или косвенно расширяют LightEntity.Интересно, связано ли это с обработкой Javassist наследования.

16:32:59,616 DEBUG AbstractEntityPersister:2773 -  Identity insert: insert into Questions (fieldWidth, questionNumber, questionOrder, questionText, required, toolTip) values (?, ?, ?, ?, ?, ?)
16:32:59,619 ERROR BasicLazyInitializer:165 - Javassist Enhancement failed: com.function1.formbuilder.client.model.Question
java.lang.RuntimeException: duplicate method: getProxyInformation in com.function1.formbuilder.client.model.Question_$$_javassist_5
     at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:344)
     at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:314)
     at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:273)
     at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxyFactory(JavassistLazyInitializer.java:162)
     at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.postInstantiate(JavassistProxyFactory.java:66)
     at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:188)
     at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:151)
     at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:78)
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
     at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
     at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:107)
     at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:135)
     at org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
     at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:323)
     at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:456)
     at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:113)
     at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:87)
     at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:267)
     at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1341)
     at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
     at com.function1.common.F1HibernateUtil.<clinit>(F1HibernateUtil.java:22)
     at com.function1.formbuilder.server.StartupServlet.init(StartupServlet.java:26)
Caused by: java.lang.RuntimeException: duplicate method: getProxyInformation in com.function1.formbuilder.client.model.Question_$$_javassist_0
    at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:344)
    at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:314)
    at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:273)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxyFactory(JavassistLazyInitializer.java:162)
    ... 42 more
Caused by: javassist.bytecode.DuplicateMemberException: duplicate method: getProxyInformation in com.function1.formbuilder.client.model.Question_$$_javassist_0
    at javassist.bytecode.ClassFile.testExistingMethod(ClassFile.java:593)
    at javassist.bytecode.ClassFile.addMethod(ClassFile.java:577)
    at javassist.util.proxy.ProxyFactory.override(ProxyFactory.java:658)
    at javassist.util.proxy.ProxyFactory.overrideMethods(ProxyFactory.java:632)
    at javassist.util.proxy.ProxyFactory.make(ProxyFactory.java:552)
    at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:335)

Есть какие-нибудь идеи о том, как решить эту проблему?

Это было полезно?

Решение

Как проиллюстрировано билет в СПЯЩИЙ РЕЖИМ-37, каким - то образом getProxyInformation() получает определение дважды, возможно, с другим типом возвращаемого значения.

билет HHH-1938 предлагаемое использование cglib вместо JavaAssist в качестве усилителя байт-кода, но я не уверен, возможно ли это в вашей конфигурации.

Вы должны изменить значение

hibernate.bytecode.provider=javassist

для

hibernate.bytecode.provider=cglib

в:

<WHERE IS YOUR JBOSS>\server\default\deploy\ejb3.deployer\META-INF\ persistence.properties

И это устраняет проблему дублированного метода

(опять же, это не ваша конфигурация, но это может дать вам представление, где искать)

Другие советы

Новый javassist versoin 3.16.1-GA будет работать с дублирующими методами:

https://issues.jboss.org/browse/JASSIST-127

И были некоторые другие подобные проблемы, также исправленные для 3.16.0-GA

Javassist не допускает дублирования методов (разрешено Java5)

https://jira.jboss.org/jira/browse/JASSIST-24

Попробуйте удалить Comparable<Question> если это возможно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top