Domanda

Il mio web app sta usando GWT 2.0.2, 2.1.1 GXT, Hibernate 3.5-CR1, Javassist 3.11.0 e Gilead 1.3.1 (l'ultima da SVN).

La mia app stava funzionando bene con GWT 1.7.1 + Gilead 1.2.

Voglio approfittare di alcune delle caratteristiche di GWT 2.0, e pensato che avrei l'aggiornamento alla più recente Gilead nel processo. Indicai il nuovo file gwt.xml in Galaad 1.3. Sto anche utilizzando il nuovo net.sf.gilead.pojo.gwt.LightEntity invece di net.sf.gilead.pojo.java5.LightEntity.

Ho un paio di enti Hibernate / classi che estendono LightEntity (vale a dire una domanda, Form), così come un paio di entità / classi che estendono l'entità domanda. Non so se è importante, ma sto usando InheritanceType.JOINED per la strategia di ereditarietà nell'entità questione.

Per avere un riferimento, ecco la classe Domanda:

@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;
    }
}

La mia app ha un servlet di avvio che crea una fabbrica sessione di Hibernate. Nei registri, ottengo un errore di "metodo di duplicazione", a tutte le classi che estendono direttamente o indirettamente LightEntity. Mi chiedo se questo è un problema con la gestione di Javassist di eredità.

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)

Tutte le idee su come risolvere questo problema?

È stato utile?

Soluzione

Come illustrato da biglietto HIBERNATE-37 , in qualche modo getProxyInformation() ottiene definire due volte , eventualmente con un diverso tipo di ritorno.

biglietto HHH-1938 ha suggerito di utilizzare cglib invece di JavaAssist come esaltatore di bytecode, ma un non so se questo è possibile nella configurazione .

  

È necessario modificare il valore di

hibernate.bytecode.provider=javassist
  

per

hibernate.bytecode.provider=cglib
  

in:

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

E questo risolve il problema del metodo duplicato

(di nuovo, questa non è la configurazione ma che potrebbe darvi un idea di dove cercare)

Altri suggerimenti

Il nuovo javassist versoin 3.16.1-GA lavorerà con metodi duplicati:

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

E ci sono stati alcuni altri problemi simili fisse anche per 3.16.0-GA

Javassist non consente metodi duplicati (consentito dal Java5)

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

Prova a rimuovere Comparable<Question> se questo è possibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top