Albjenow
Albjenow

Reputation: 379

Fetch related entities as Base Type

I'm currently trying to setup a database – using Java only. Given this simple class that might appear in the average social network app:

@Entity
class User {
    @Id
    private String email;
    private String name;
    private String otherInfo;

    @ManyToMany
    private List<User> contacts;
}

When the user logs in, he should receive the basic information and the list of contacts with their basic info, but not their contacts. To reduce the amount of boiler-plate code, I want to use a standard solution like Gson. However, even with lazy fetch the whole user is loaded on gson.toJson(user).

Therefore I thought of extracting the basic infos into a base class BasicUser and changing the contacts to List<BasicUser>. Now I only need to somehow circumwent the discriminator column when I fetch the contacts – of course they are all saved as complete users on the server. Unfortunately, I don't know how to archieve that. Any ideas?

Upvotes: 1

Views: 47

Answers (3)

crizzis
crizzis

Reputation: 10716

You shouldn't have to modify your domain model just to accomodate a serialization library.

If you only want certain fields of a collection to be exposed to JSON, you could use Jackson with @JsonView (see here: How to serialize using @Jsonview with nested objects) not sure if Gson provides a similar feature as I have never used it extensively.

Upvotes: 1

Albjenow
Albjenow

Reputation: 379

Using Jackson for serialization, the problem can be solved without writing custom serialization code. BasicUser contains the getters of the attributes, I want to serialize:

public interface BasicUser {
    String getEmail();
    String getFirstName();
    String getLastName();
}

With a single annotation the contacts attribute is interpreted as a list of BasicUsers:

@Entity
public class User implements BasicUser {    
    @Id
    private String email;
    private String firstName;   
    private String lastName;

    @ManyToMany
    @JsonSerialize(contentAs = BasicUser.class)
    private List<User> contacts = new ArrayList<>();    

    // ... implemented getters
}

Upvotes: 1

Cepr0
Cepr0

Reputation: 30349

If you need to get only part of the entity you can use projections. In your case it can be, for example, like this:

public interface BaseUser {
    String getEmail();
    String getName();
    String getOtherInfo();
}

public interface UserRepo extends JpaRepository <User, String> {
    List<BaseUser> findAllBy();
}

Upvotes: 1

Related Questions