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

时间:2018-07-09 13:06:50

标签: java hibernate tomcat jpa

我的Web服务应返回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包装在单例列表中(不再有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);
        }

    }

}

让我知道您是否需要其他信息。谢谢!

1 个答案:

答案 0 :(得分:0)

我删除了这个依赖关系,我在回答另一个问题后添加了这个依赖关系。

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

不知道问题出在什么地方,但现在可以解决。也许有人可以解释。