JPA 2.1实体,为什么我总是让实体自己而不是实体的主键?

时间:2015-02-28 23:13:46

标签: entity-framework jpa entity primary-key

这是我之前提问的一个更深层次的挖掘者。

我有一个来自Postgresql服务器的NetBeans生成的实体类。源代码是:

package com.longz.ozssc.domain;

import javax.persistence.*;
import java.sql.Time;
import java.util.Arrays;

/**
 * Created by cidylong on 12/01/2015.
*/
@Entity
@Table(name = "file", schema = "public", catalog = "ozssc")
public class FileEntity {
    private String fileId;
    private String referId;
    private String fileName;
    private String fileType;
    private byte[] fileData;
    private Time createdDatatime;

@Id
@Column(name = "file_id", nullable = false, insertable = true, updatable = true, length = 2147483647)
public String getFileId() {
    return fileId;
}

public void setFileId(String fileId) {
    this.fileId = fileId;
}

@Basic
@Column(name = "refer_id", nullable = false, insertable = true, updatable = true, length = 2147483647)
public String getReferId() {
    return referId;
}

public void setReferId(String referId) {
    this.referId = referId;
}

@Basic
@Column(name = "file_name", nullable = false, insertable = true, updatable = true, length = 2147483647)
public String getFileName() {
    return fileName;
}

public void setFileName(String fileName) {
    this.fileName = fileName;
}

@Basic
@Column(name = "file_type", nullable = true, insertable = true, updatable = true, length = 2147483647)
public String getFileType() {
    return fileType;
}

public void setFileType(String fileType) {
    this.fileType = fileType;
}

@Basic
@Column(name = "file_data", nullable = false, insertable = true, updatable = true)
public byte[] getFileData() {
    return fileData;
}

public void setFileData(byte[] fileData) {
    this.fileData = fileData;
}

@Basic
@Column(name = "created_datatime", nullable = false, insertable = true, updatable = true)
public Time getCreatedDatatime() {
    return createdDatatime;
}

public void setCreatedDatatime(Time createdDatatime) {
    this.createdDatatime = createdDatatime;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    FileEntity that = (FileEntity) o;

    if (createdDatatime != null ? !createdDatatime.equals(that.createdDatatime) : that.createdDatatime != null)
        return false;
    if (!Arrays.equals(fileData, that.fileData)) return false;
    if (fileId != null ? !fileId.equals(that.fileId) : that.fileId != null) return false;
    if (fileName != null ? !fileName.equals(that.fileName) : that.fileName != null) return false;
    if (fileType != null ? !fileType.equals(that.fileType) : that.fileType != null) return false;
    if (referId != null ? !referId.equals(that.referId) : that.referId != null) return false;

    return true;
}

@Override
public int hashCode() {
    int result = fileId != null ? fileId.hashCode() : 0;
    result = 31 * result + (referId != null ? referId.hashCode() : 0);
    result = 31 * result + (fileName != null ? fileName.hashCode() : 0);
    result = 31 * result + (fileType != null ? fileType.hashCode() : 0);
    result = 31 * result + (fileData != null ? Arrays.hashCode(fileData) : 0);
    result = 31 * result + (createdDatatime != null ? createdDatatime.hashCode() : 0);
    return result;
}
@Override
public String toString() {
    return "com.longz.ozssc.model.FileEntity[ fileId=" + fileId + " ]";
}

}

这是我在项目中使用的非常流行的实体类。实体主键是fileId,有一组getter / setter对可以访问实体中的私有属性,例如setFileId(String fileId)和getFileId()。

我的远程界面是:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.longz.ozssc.remote;

import com.longz.ozssc.model.FileEntity;
import java.util.List;
import javax.ejb.Remote;

/**
 *
 * @author cidylong
*/
@Remote
public interface FileEntityFacadeRemote {

  void create(FileEntity fileEntity);

  void edit(FileEntity fileEntity);

  void remove(FileEntity fileEntity);

  FileEntity find(Object id);

  List<FileEntity> findAll();

  List<FileEntity> findRange(int[] range);

  int count();

}

我的EJB工具是:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.longz.ozssc.ejb;

import com.longz.ozssc.model.FileEntity;
import com.longz.ozssc.remote.FileEntityFacadeRemote;
import com.longz.ozssc.remote.OzsscIdSequenceFacadeRemote;
import com.longz.ozssc.utils.datatime.DateTimeAssistant;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.apache.commons.lang3.StringUtils;

/**
 *
 * @author cidylong
 */
@Remote(FileEntityFacadeRemote.class)
@Stateless(mappedName="fileEntityFacadeEJB")
public class FileEntityFacade extends AbstractFacade<FileEntity> implements FileEntityFacadeRemote {
    @PersistenceContext(unitName = "OzsscJPANBPU")
    private EntityManager em;

  @Override
  protected EntityManager getEntityManager() {
    return em;
}

  public FileEntityFacade() {
    super(FileEntity.class);
}

  @EJB
  private OzsscIdSequenceFacadeRemote ozsscIdSqFaRemote;

  @Override
  public List<FileEntity> findAll(){
    Query query = em.createNamedQuery("FileEntity.findAllOrderByCreated");
    return new LinkedList<FileEntity>(query.getResultList());
    /*return super.findAll();*/
}

}

每当我调用实体方法getFileId()时,

 String fileId = (FileEntity)fileEntity.getFileId();

假设我将从实体获得一个字符串返回类似于:

**FILES20150200013**. 

但我的实体总是回归:

**com.longz.ozssc.model.FileEntity[ fileId= FILES20150200013 ]**

此返回值正是toString()打印输出的其他实体方法。这意味着,

当我调用getFileId()方法访问实体的主键时,实体会向我返回一个完整的实体值,而不是返回主键。

我的代码或实体访问方法中的某些错误有什么问题吗?

任何建议都是受欢迎的,并且非常赞赏。

编辑:

当我尝试使用JPA 2.0提供的方法访问实体的主键时:

Object identifier = 
                EntityManagerFactory.getPersistenceUnitUtil().getIdentifier(fileEntity);

我得到同样错误的回报。烦扰??

1 个答案:

答案 0 :(得分:0)

我自己发现了这个问题。

实际上。我用java客户端测试它包括WebLogic客户端库,我发现它在Java客户端中运行良好。

然后,我将相同的测试代码放在Spring MVC上下文中,而不是工作。 Spring MVC控制器总是给出错误的返回值。这很有趣。

作为替代解决方案。我使用Spring表单对象通过使用ABN字符串而不是使用FirmEntity重新组织参数,然后我将ABN字符串传递给EJB,我得到了正确的返回。

这可能可以帮助遇到同样问题的其他人。我相信这个问题是由Spring Frameworks的AOP功能引起的,当你使用这些功能时,应该非常谨慎地使用错误的字符串来返回值。