我正在尝试使用JAX-RS构建RESTendpoint,以JSONhtml" target="_blank">格式返回JPA实体。我发现了一个类似的问题,但即使在我的案例中应用了所有类似的更改后,我仍然得到HTTP 500内部错误代码,Glassfish没有生成日志或显示与此请求相关的错误消息。
这是代码:
实体类:
@XmlRootElement
@Entity
@Table(name = "TB_BANNER_IMAGE")
public class BannerImage extends BaseEntity<Integer> {
private FileReference fileReference;
private String type;
private String labelTitle;
private String labelText;
public BannerImage() {}
@Id
@TableGenerator(name="genBannerImage", table="TB_ID_GENERATOR",
pkColumnName="ID_NAME", valueColumnName="ID_VAL",
pkColumnValue="TB_BANNER_IMAGE", allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, generator="genBannerImage")
@Column(name = "ID_BANNER_IMAGE", unique = true, nullable = false)
public Integer getId() {
return super.getId();
}
@Override
public void setId(Integer id) {
super.setId(id);
}
@Column(name="TYPE")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID_FILE_REFERENCE", nullable=false)
public FileReference getFileReference() {
return fileReference;
}
public void setFileReference(FileReference fileReference) {
this.fileReference = fileReference;
}
@Column(name="LABEL_TITLE")
public String getLabelTitle() {
return labelTitle;
}
public void setLabelTitle(String labelTitle) {
this.labelTitle = labelTitle;
}
@Column(name="LABEL_TEXT")
public String getLabelText() {
return labelText;
}
public void setLabelText(String labelText) {
this.labelText = labelText;
}
}
和
@XmlRootElement
@Entity
@Table(name = "TB_FILE_REFERENCE")
public class FileReference extends BaseNamedEntity<String> {
private String type;
public FileReference() {}
@Id
@TableGenerator(name="genFileReference", table="TB_ID_GENERATOR",
pkColumnName="ID_NAME", valueColumnName="ID_VAL",
pkColumnValue="TB_FILE_REFERENCE", allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, generator="genFileReference")
@Column(name = "ID_FILE_REFERENCE", unique = true, nullable = false)
public String getId() {
return super.getId();
}
@Override
public void setId(String id) {
super.setId(id);
}
@Column(name = "TYPE")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
基本泛型超类:
@MappedSuperclass
public abstract class BaseNamedEntity<ID extends Serializable> implements INamedEntity<ID>, Comparable, Serializable {
private ID id;
private String name;
protected BaseNamedEntity() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Transient
public ID getId() {
return id;
}
public void setId(ID id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof BaseNamedEntity) {
BaseNamedEntity base2 = (BaseNamedEntity) obj;
if (this.getId() != null && base2.getId() != null) {
return this.getId().equals(base2.getId());
}
}
return false;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return name;
}
@Override
public int compareTo(Object arg0) {
if (this == arg0) {
return 0;
}
BaseNamedEntity<ID> other = (BaseNamedEntity<ID>) arg0;
return getName().compareTo(other.getName());
}
}
应用程序JAX-RS配置:
@ApplicationPath("/rest")
public class PortalApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
// register root resource
classes.add(BannerImageService.class);
return classes;
}
}
服务等级:
@Path("/banner")
public class BannerImageService extends BaseServiceFacade<BannerImage, Integer> {
public BannerImageService() {
super(BannerImage.class);
}
@Override
protected boolean validateEntity(BannerImage entity) {
if (entity != null
&& entity.getId() != null
&& entity.getFileReference() != null
&& entity.getFileReference().getName() != null
&& RegexUtil.getInstance().validateFileName(
entity.getFileReference().getName())) {
return true;
}
return false;
}
@Override
protected String getDefaultQuery() {
return null;
}
@Override
protected boolean validateID(Integer id) {
return RegexUtil.getInstance().validateIntegerID(id);
}
@Override
public Crud<BannerImage, Integer> lookupService() throws ServiceLocatorException {
return ServiceLocator.getInstance()
.getLocalHome(ServicesConstants.BANNER_IMAGE_SERVICE);
}
}
和
public abstract class BaseServiceFacade<T extends IEntity<ID>, ID extends Serializable> implements ServiceFacadeRest<T, ID> {
protected static final Logger log = Logger.getLogger("BaseServiceFacade");
protected Crud<T, ID> service;
protected Class<T> clazz;
public BaseServiceFacade(Class<T> classe) {
clazz = classe;
}
protected abstract boolean validateEntity(T entity);
protected abstract boolean validateID(ID id);
protected abstract String getDefaultQuery();
protected abstract Crud<T, ID> lookupService() throws ServiceLocatorException;
public Crud<T,ID> getService() {
try {
if (service == null) {
service = lookupService();
}
}catch (Exception ex) {
logException(ex);
}
return service;
}
public void setService(Crud<T,ID> service) {
this.service = service;
}
public Class<T> getClazz() {
return clazz;
}
public void serviceException(ServiceException ex) {
log.log(Level.INFO, ex.getMessage());
}
public void logException(Exception ex) {
log.log(Level.INFO, ex.getMessage());
ex.printStackTrace();
}
@Override
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/query")
public List<T> query() {
try {
String defaultQuery = getDefaultQuery();
if (defaultQuery != null) {
return getService().search(defaultQuery);
} else {
return getService().findAll(clazz);
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return null;
}
@Override
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/get/{id}")
public T get(@PathParam("id") ID id) {
try {
if (validateID(id)) {
return getService().findById(clazz, id);
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return null;
}
@Override
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/create")
public T create(T entity) {
try {
if (validateEntity(entity)) {
getService().insert(entity);
return entity;
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return null;
}
@Override
@PUT
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/update/{id}")
public T update(T entity) {
try {
if (validateEntity(entity)) {
return getService().update(entity);
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return null;
}
@Override
@DELETE
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
@Path("/delete/{id}")
public boolean delete(@PathParam("id") ID id) {
try {
if (validateID(id)) {
return getService().delete(clazz, id);
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return false;
}
}
当我撞到localhost/app/rest/banner/query
我得到一个HTTP 500内部错误代码页,Glassfish返回一个空的超文本标记语言:“服务器遇到一个内部错误,阻止它完成此请求。”
当我尝试搜索日志文件时,我没有看到错误,并且调用是通过服务层进行的,然后返回:
[2014-03-19T20:39:28.898-0300] [glassfish 4.0] [FINE] [] [org.eclipse.persistence.session.file[tid: _ThreadID=20 _ThreadName=http-listener-1(1)] [timeMillis: 1395272368898] [levelValue: 500] [[
SELECT ID_BANNER_IMAGE, LABEL_TEXT, LABEL_TITLE, TYPE, ID_FILE_REFERENCE FROM TB_BANNER_IMAGE]]
即使日志显示没有错误并且正在进行调用,从UI中我实际上看不到错误源是什么,只有默认的HTTP 500内部错误页面。
在注释掉FileReference类的@ManyToOne JPA实体关系后,我可以得到HTTP 200和JSON输出,如:
[
{
"@type":"bannerImage",
"id":1,
"type":"main"
},
{
"@type":"bannerImage",
"id":2,
"type":"main"
},
...
在实体关系中,如果切换到@manytone(fetch=FetchType.LAZY)
然后我得到了一个JSON响应,所以我猜问题与原始请求期间FileReference实例为null有关。
[
{
"@type":"bannerImage",
"id":1,
"fileReference":{
"id":"2bdbb063d0d0ee2939c89763945d9d9e",
"name":"banner1.png",
"type":"image/png"
},
"type":"main"
},
{
"@type":"bannerImage",
"id":2,
"fileReference":{
"id":"b33fa2041f2989f58a25dca2a6a35025",
"name":"banner2.png",
"type":"image/png"
},
"type":"main"
},
但是有一个@type属性不在我的模型中,它是与之一起创建的,我无法准确地确定它来自哪里,可能是因为“query”方法的响应类型是一个泛型类型列表
7年后,他遇到了同样的500人,但信息很少。
Weblogic12.2.1.3,Eclipse Link 2.6.5。
指定FetchType。懒惰于@OneToMany
应用了XmlInvereseReference(mappedBy={column on entity owning the relationship})<没有在任何实体上应用@XmlRootElement。
这将返回JPA对象图的完整JSON表示。
[甲骨文参考文献][1]
[1]:http://wiki.eclipse.org/EclipseLink/Examples/REST/GettingStarted/XmlBinding
启用异常跟踪日志记录-
@Provider
public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
exception.printStackTrace();
return Response.status(500).build();
}
}
该问题恰好与实体映射FetchType有关。重构后的LAZY我可以在包含以下内容后获得正确的JSON响应:
在BannerImageService上。java:
@Override
protected String getDefaultQuery() {
return BannerImageDAO.GET_ALL_FETCH_FILE_REF;
}
在BannerImageDAO:
public static final String GET_ALL_FETCH_FILE_REF = "SELECT a FROM BannerImage a join fetch a.fileReference";
手动获取关系后,JSON响应是正确的。唯一奇怪的是Glassfish没有记录任何异常或任何与HTTP 500内部错误相关的信息,但我想这是另一个主题。
问题内容: 我有一个返回内部服务器错误(500)的php应用程序时出现问题,但错误日志中未显示任何内容。 现在,我知道我要运行的内容有错误,我知道缺少某些文件,但没有丢失,但是应该在apache错误日志中显示某些内容(否则,我应该如何确切知道丢失的内容)。 我创建了一个测试脚本,该脚本在相同的vhost配置下出错,并且这些错误显示得很好,因此一切似乎都已正确配置到php / apache。是否有某
我已经看了很多教程,但我无法使我的简单JAX-RS应用程序工作。Tomcat总是返回错误404。 要获取类的应用程序: 我的JAX-RS文件: web.xml http://localhost:8080/msm-master/resources/hello/ 编辑:已添加Tomcat控制台输出:
在我的Spring/MySql系统中,我有一些Jpa实体,它们通过父关系上的joinTable在OneToMany关系中连接。在这种情况下,一个帖子有很多评论。 如果我尝试删除Post实体,问题是生成的SQL试图删除仍在连接表中的注释,从而触发外键冲突。 什么是正确的方法: 删除连接表项 删除连接表左侧父关系实体 删除连接表右侧子关系实体 要记住的一些事情: 还有其他实体通过oneTo多项关系拥有
我是一个初学者,学习JPA,为了练习,我在这个问题上工作,我有两个实体班Person和Gym。 Person有:-id(自动生成)-name-age-gym(多对一映射) 在我的服务课上,这就是我正在做的
问题内容: 我正在努力弄清Java中的一些概念: JSR:描述规格,但不包含实际的实现。例如,http://jsr311.java.net/是“ RESTful Web服务的Java™API”的“主页”。它用作JSR-311的所有实现的通用参考。 可以从http://mvnrepository.com/artifact/javax.ws.rs/jsr311-api下载JSR-311的接口(?),但
对于新学生和新课程的情况,它工作得很好,但是在新课程和现有学生的情况下,我会从数据库中抛出一个唯一的约束冲突。关系类似于下面。 在持久化之前,我尝试使用entitymanager查找一个学生,如果该学生存在,则使用该实例而不是新的学生实例。这也不起作用,它仍然尝试执行插入而不是更新