1

我在我的网络应用程序中使用 GWT RequestFactory + Hibernate + Spring。我有 Principal 和 Profile 实体,它们以一对一的方式相互关联。它们共享相同的主键。

在客户端,我编写了这样的代码,导致 NullPointerException:

如果我排除“principal.setProfile(profile);” 代码行,主体实体将被成功存储。我无法弄清楚为什么不能将配置文件实体与主体一起存储。

任何建议将不胜感激。提前致谢!

public RegistrationPanel() {
        TarantulaFactory factory = GWT.create(TarantulaFactory.class);
        factory.initialize(new SimpleEventBus());

        PrincipalRequestContext principalCtx = factory.createPrincipalRequest();
        ProfileRequestContext profileCtx = factory.createProfileRequest();

        PrincipalProxy principal = principalCtx.create(PrincipalProxy.class);
        principal.setLogin("Billy");
        principal.setPassword("Corgan");

        ProfileProxy profile = profileCtx.create(ProfileProxy.class);
        profile.setNickname("A");
        profile.setName("b");        
        profile.setEmail("ABCD34@gmail.com");
        profile.setBirthDate(new Date());
        profile.setCurrentLocation("Chicago");

        principal.setProfile(profile);
        profile.setPrincipal(principal);


        principalCtx.save(principal).fire();
}

堆栈跟踪:

//------------------------------------------------------------------------

21:09:24.992 [ERROR] [application] Uncaught exception escaped
    java.lang.NullPointerException: null
    at            com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$MyConstraintViolation.<init>(AbstractRequestContext.java:434)
    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$StandardPayloadDialect.processPayload(AbstractRequestContext.java:366)
    at com.google.web.bindery.requestfactory.shared.impl.AbstractRequestContext$5.onTransportSuccess(AbstractRequestContext.java:1151)
    at com.google.web.bindery.requestfactory.gwt.client.DefaultRequestTransport$1.onResponseReceived(DefaultRequestTransport.java:136)
    at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:258)
    at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:412)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
    at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
    at sun.reflect.GeneratedMethodAccessor35.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
    at java.lang.Thread.run(Thread.java:722)

//------------------------------------------------------------------------

下面是实体、代理和 RequestFactory 的源代码。

以下是实体类:

配置文件.java

package com.szybieka.tarantula.core.domain;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;

/**
* 
* A Profile representing the user profile entity. Each user has single profile.
* Profile and {@link Principal} entities relate to each other as one-to-one.
* Shared primary key is used to join corresponding tables.
* 
* @author Zmicer Szybieka
* 
*/

@Entity
@Table(name = "profile", uniqueConstraints = { @UniqueConstraint(
columnNames = "id") })
public class Profile {

    @Id
    @NotNull
    @Column(name = "id", unique = true)
    @GeneratedValue(generator = "gen")
    @GenericGenerator(name = "gen", strategy = "foreign",
    parameters = @Parameter(name = "property", value = "principal"))
    private Long id;

    @Length(min = 1, max = 30)
    private String nickname;

    @Length(max = 30)
    private String name;

    @Column(name = "birth_date")
    private Date birthDate; // date of birth, e.g. "20.01.1985"

    @Length(max = 30)
    @Column(name = "current_location")
    private String currentLocation; // current location city, e.g. "NYC"

    @Email
    private String email;

    private Date version;

    @OneToOne(mappedBy = "profile", cascade = CascadeType.ALL)
    private Principal principal; // the user principal corresponding to the
                             // profile

    public Profile() {
    }

    public Long getId() {
       return id;
    }

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

// omit setters/getters
}

校长.java

package com.szybieka.tarantula.core.domain;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.validator.constraints.Length;

/**
 * A Principal representing an identity used to determine access rights to
 * application. Principal relates to {@link Profile} entity as one-to-one.
 * Shared primary key is used to join corresponding tables.
 * 
 * @author Zmicer Szybieka
 * 
*/

@Entity
@Table(name = "principal", uniqueConstraints = { @UniqueConstraint(
    columnNames = "id") })
public class Principal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Length(max = 20)
    private String login;

    @Length(max = 10)
    private String password;

    private Date version;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private Profile profile;

    public Principal() {
    }

    public Long getId() {
       return id;
    }

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

    // omit setters/getters
}

我使用 RequestFactory 与服务器端连接。

这是我的请求工厂:

狼蛛工厂.java

package com.szybieka.tarantula.gwt.client.requestfactory;

import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;  
import com.google.web.bindery.requestfactory.shared.Service;
import com.szybieka.tarantula.gwt.client.proxy.PrincipalProxy;
import com.szybieka.tarantula.gwt.client.proxy.ProfileProxy;
import com.szybieka.tarantula.gwt.server.locator.PrincipalServiceLocator;
import com.szybieka.tarantula.gwt.server.locator.ProfileServiceLocator;
import com.szybieka.tarantula.gwt.server.service.PrincipalService;
import com.szybieka.tarantula.gwt.server.service.ProfileService;

public interface TarantulaFactory extends RequestFactory {

    PrincipalRequestContext createPrincipalRequest();

    ProfileRequestContext createProfileRequest();

    @Service(value = ProfileService.class,
        locator = ProfileServiceLocator.class)
    public interface ProfileRequestContext extends RequestContext {

        Request<Void> save(ProfileProxy profile);

        Request<ProfileProxy> findProfile(Long id);
    }

    @Service(value = PrincipalService.class,
        locator = PrincipalServiceLocator.class)
    public interface PrincipalRequestContext extends RequestContext {

        Request<PrincipalProxy> findPrincipal(String login, String password);

        Request<PrincipalProxy> findPrincipal(Long id);

        Request<PrincipalProxy> findPrincipalByLogin(String login);

        Request<Void> save(PrincipalProxy principal);

        Request<Void> remove(PrincipalProxy principal);
    }
}

以下是实体类的代理:

ProfileProxy.java

package com.szybieka.tarantula.gwt.client.proxy;

import java.util.Date;

import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.szybieka.tarantula.core.domain.Profile;
import com.szybieka.tarantula.gwt.server.locator.ProfileLocator;

@ProxyFor(value = Profile.class, locator = ProfileLocator.class)
public interface ProfileProxy extends EntityProxy {

    Long getId();

    void setId(Long id);

    // omit other getter/setter methods

}

PrincipalProxy.java

package com.szybieka.tarantula.gwt.client.proxy;

import com.google.web.bindery.requestfactory.shared.EntityProxy;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.szybieka.tarantula.core.domain.Principal;
import com.szybieka.tarantula.gwt.server.locator.PrincipalLocator;

@ProxyFor(value = Principal.class, locator = PrincipalLocator.class)
public interface PrincipalProxy extends EntityProxy {

    Long getId();

    String getLogin();

    // omit other getter/setter methods
}
4

1 回答 1

1

ARequestContext是您最终触发以发送到服务器进行处理的批处理请求的构建器。所有代理都必须在批处理请求中创建和编辑。RequestContext

删除您的使用ProfileRequestContext并替换profileCtx.create(ProfileProxy.class)principalCtx.create(ProfileProxy.class).

于 2013-10-20T22:29:30.240 回答