java - 返回 JPA 实体导致内部服务器错误

标签 java hibernate tomcat jpa

我的 WebService 在应该返回 200 时返回 500 - 内部服务器错误。 首先,这是一些代码:

实体类:

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "songList")
@Entity
public class SongList {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name="owner")
    private User owner;

    @OneToMany(
            fetch = FetchType.EAGER,
            orphanRemoval = true
        )
    private List<Song> songs;

    private Boolean isPublic;

    public SongList() {}

    public Integer getId() {
        return id;
    }

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

    public Boolean getIsPublic() {
        return isPublic;
    }

    public void setIsPublic(Boolean isPublic) {
        this.isPublic = isPublic;
    }

    public User getOwner() {
        return owner;
    }

    public void setOwner(User owner) {
        this.owner = owner;
    }

    public List<Song> getSongs() {
        if(songs == null) {
            songs = new ArrayList<>();
        }
        return songs;
    }

    public void setSongs(List<Song> songs) {
        this.songs = songs;
    }

}

我的网络服务中有问题的方法:

@GET
    @Path("/{userId}/songLists")
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public Response getAllSongLists(@HeaderParam("Authorization") String token, @PathParam("userId") String userId) {
        if(!TokenStorage.getInstance().isValid(token)) {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }

        User user = usersDao.findUserByUserId(userId);
        if(user == null) {
            return Response.status(Response.Status.NOT_FOUND).entity("No user found with id " + userId).build();
        }

        boolean hasPrivateAccess = TokenStorage.getInstance().isValidForUser(userId, token);
        if(hasPrivateAccess) {
            return Response.ok(user.getSongLists()).build();
        }

        List<SongList> publicSongLists = user.getSongLists()
                .stream()
                .filter(SongList::getIsPublic)
                .collect(Collectors.toList());

        System.err.println("publicSongLists: " + publicSongLists.size());

        for(SongList s : user.getSongLists()) {
            System.err.println("xxxx " + s.getIsPublic());
        }

        return Response.ok(publicSongLists).build();
    }

    @GET
    @Path("/{userId}/songLists/{songListId}")
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public Response getSongList(@HeaderParam("Authorization") String token, @PathParam("userId") String userId, @PathParam("songListId") Integer songListId) {
        if(!TokenStorage.getInstance().isValid(token)) {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
        User user = usersDao.findUserByUserId(userId);
        if(user == null) {
            return Response.status(Response.Status.NOT_FOUND).entity("No user found with id " + userId).build();
        }

        boolean hasPrivateAccess = TokenStorage.getInstance().isValidForUser(userId, token);

        for(SongList songList : user.getSongLists()) {
            if(songList.getId().equals(songListId)) {
                if(songList.getIsPublic() || hasPrivateAccess) {
                    System.err.println("xxxxxx Songlist return: " + songList.getId());
                    // here is the problem. prints xxxxxx SongList return: 12 but internal server error
                    return Response.ok(songList).build();
                }

                return Response.status(Response.Status.UNAUTHORIZED).build();
            }
        }

        return Response.status(Response.Status.NOT_FOUND).entity("No songList found with id " + songListId).build();
    }

奇怪的是 getAllSongLists() 按预期工作,但 getSongList() 返回 500。 该方法返回此处,因为它打印“xxxxxx SongList return 12”:

System.err.println("xxxxxx Songlist return: " + songList.getId());
return Response.ok(songList).build();

也像这样将 songList 包装在一个 singletonList 中(不再有 500 个):

return Response.ok(Collections.singletonList(songList)).build();

为什么我可以返回 List<SongList>但不是 SongList ? 几个小时前它曾经工作过,但我无法弄清楚我的哪些更改破坏了它。 (我知道应该做一些单元测试:/)

基本上,在修复另一个错误时,我添加并删除了一些依赖项,但我很确定我仍然拥有所需的那些以及过去工作的版本......

所以这是我的 pom.xml :

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>de.htwBerlin.ai.kbe</groupId>
    <artifactId>songsRX</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>songsRX</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-jaxb</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.12.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.2.11</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>songsRX</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <!-- mvn tomcat8:run-war -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat8-maven-plugin</artifactId>
                <version>3.0-r1756463</version>
            </plugin>
        </plugins>
    </build>
</project>

为了以防万一这里是Song.java自从它上次工作以来我没有改变:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "song")
@Entity
public class Song {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String title;
    private String artist;
    private String album;
    private Integer released;

    public Song() {}

    private Song(Builder builder) {
        this.id = builder.id;
        this.title = builder.title;
        this.artist = builder.artist;
        this.album = builder.album;
        this.released = builder.released;
    }

    public Integer getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getAlbum() {
        return album;
    }

    public void setAlbum(String album) {
        this.album = album;
    }

    public Integer getReleased() {
        return released;
    }

    public void setReleased(Integer released) {
        this.released = released;
    }

    @Override
    public String toString() {
        return String.format("Song [id=%d, title=%s, artist=%s, album=%s, released=%d]", id, title, artist, album, released);
    }

    public static class Builder {

        private int id;
        private String title;
        private String artist;
        private String album;
        private Integer released;

        public Builder id(int id) {
            this.id = id;
            return this;
        }

        public Builder title(String title) {
            this.title = title;
            return this;
        }

        public Builder artist(String artist) {
            this.artist = artist;
            return this;
        }

        public Builder album(String album) {
            this.album = album;
            return this;
        }

        public Builder released(Integer released) {
            this.released = released;
            return this;
        }

        public Song build() {
            return new Song(this);
        }

    }

}

如果您需要任何其他信息,请告诉我。谢谢!

最佳答案

我删除了这个依赖项,这是我在回答我遇到的另一个问题后添加的。

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>2.26</version>
</dependency>

不知道到底是什么问题,但现在可以了。也许有人可以解释。

关于java - 返回 JPA 实体导致内部服务器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51246327/

相关文章:

Java无法正确显示字符串的最后一个字母?

Java - 在设置子字段之前在 super 实例化期间调用抽象方法的问题

java - 如何在不使用 java 表的 id 属性的情况下迭代表并在 <td> 标记中获取数据

eclipse - Hive JDBC Web 应用程序中的 "Driver not capable"异常

jsf - 如何在Tomcat上安装和使用CDI?

java.lang.UnsupportedClassVersionError : yy/ii : Unsupported major. 次要版本 51.0

java - HTML 包含 "<"和 ">"字符的 JLabel

hibernate - tomcat 重新启动 => 找不到 SessionFactory [uuid=...,name=null]

hibernate - Grails 3.0.9。如何测试Hibernate二级缓存?

java - 如何查找/更改 hibernate 查询