Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to exclude fields of a referance object of same class #44

Open
Devlad91 opened this issue May 18, 2017 · 1 comment
Open

How to exclude fields of a referance object of same class #44

Devlad91 opened this issue May 18, 2017 · 1 comment

Comments

@Devlad91
Copy link

Devlad91 commented May 18, 2017

This is a great library ,I am using this library for a while now (since 0.12-SNAPSHOT) , and it is working like a charm. (At present i am using 0.16-SNAPSHOT)
Recently I am facing a problem with my one of the Use cases, let me place my code first

# User class

public class User {

    private String name;
    private String emailId;
    private String mobileNo;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    public String getMobileNo() {
        return mobileNo;
    }

    public void setMobileNo(String mobileNo) {
        this.mobileNo = mobileNo;
    }

}

# ScreenInfoPojo class

public class ScreenInfoPojo {

    private Long id;
    private String name;
    private ScreenInfoPojo parentScreen;
    private User createdBy;
    private User lastUpdatedBy;

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ScreenInfoPojo getParentScreen() {
        return parentScreen;
    }

    public void setParentScreen(ScreenInfoPojo parentScreen) {
        this.parentScreen = parentScreen;
    }

    

    public User getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(User createdBy) {
        this.createdBy = createdBy;
    }

    public User getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(User lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    } 

# Run code

public class TestMain {
    public static void main(String[] args) throws JsonProcessingException {
        User user=new User();
        user.setName("ABC");
        user.setEmailId("dev@abc123.com");
        user.setMobileNo("123456789");
        
        ScreenInfoPojo screen1=new ScreenInfoPojo();
        screen1.setId(1l);
        screen1.setName("Screen1");
        screen1.setCreatedBy(user);
        screen1.setLastUpdatedBy(user);
        
        ScreenInfoPojo screen2=new ScreenInfoPojo();
        screen2.setId(2l);
        screen2.setName("Screen2");
        screen2.setParentScreen(Screen1);
        screen2.setCreatedBy(user);
        screen2.setLastUpdatedBy(user);
        
        ScreenInfoPojo screen3=new ScreenInfoPojo();
        screen3.setId(3l);
        screen3.setName("Screen3");
        screen3.setParentScreen(Screen2);
        screen3.setCreatedBy(user);
        screen3.setLastUpdatedBy(user);
        
        ScreenInfoPojo screen4=new ScreenInfoPojo();
        screen4.setId(4l);
        screen4.setName("Screen4");
        screen4.setParentScreen(Screen3);
        screen4.setCreatedBy(user);
        screen4.setLastUpdatedBy(user);
        
        List<ScreenInfoPojo> screens=new ArrayList<>();
        screens.add(screen1);
        screens.add(screen2);
        screens.add(screen3);
        screens.add(screen4);
        
        ObjectMapper mapper = new ObjectMapper().registerModule(new JsonViewModule());
        String json = mapper.writeValueAsString(JsonView.with(screens).onClass(ScreenInfoPojo.class, Match.match()
                .exclude("*")
                .include("id","name","createdBy.name","lastUpdatedBy.mobileNo","parentScreen.id")));
        System.out.println("json"+json);
    }    

# Result

[{
	"id": 1,
	"name": "Screen1",
	"parentScreen": null,
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 2,
	"name": "Screen2",
	"parentScreen": {
		"id": 1,
		"name": "Screen1",
		"parentScreen": null,
		"createdBy": {},
		"lastUpdatedBy": {}
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 3,
	"name": "Screen3",
	"parentScreen": {
		"id": 2,
		"name": "Screen2",
		"parentScreen": {
			"id": 1,
			"name": "Screen1",
			"parentScreen": null,
			"createdBy": {},
			"lastUpdatedBy": {}
		},
		"createdBy": {},
		"lastUpdatedBy": {}
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 4,
	"name": "Screen4",
	"parentScreen": {
		"id": 3,
		"name": "Screen3",
		"parentScreen": {
			"id": 2,
			"name": "Screen2",
			"parentScreen": {
				"id": 1,
				"name": "Screen1",
				"parentScreen": null,
				"createdBy": {},
				"lastUpdatedBy": {}
			},
			"createdBy": {},
			"lastUpdatedBy": {}
		},
		"createdBy": {},
		"lastUpdatedBy": {}
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}]




#Expected Result

[{
	"id": 1,
	"name": "Screen1",
	"parentScreen": null,
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 2,
	"name": "Screen2",
	"parentScreen": {
		"id": 1
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 3,
	"name": "Screen3",
	"parentScreen": {
		"id": 2
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}, {
	"id": 4,
	"name": "Screen4",
	"parentScreen": {
		"id": 3
	},
	"createdBy": {
		"name": "ABC"
	},
	"lastUpdatedBy": {
		"mobileNo": "123456789"
	}
}]

#Problem
In my use case I have a class ScreenInfoPojo which refers to same class as parentScreen ,
I am trying to fetch specific field/fields of parent ( "parentScreen.id") instate I am getting all fields that I have defined on child/target Object ("id","name","createdBy.name","lastUpdatedBy.mobileNo","parentScreen.id") and parent response is again recursive ! One thing i observed that It is only happening in case of a class has its own reference , I placed User class reference as two different field createdBy and lastUpdatedBy and tried to fetch "name" and "mobileNo" respectively worked just fine.
Can you suggest any solution for this problem?

Thanks

@monitorjbl
Copy link
Owner

So this isn't possible in the latest release, for good reason. There are two ways that patterns can be matched: by explicit class association and by the dot-path. In the current implementation, the class matcher is always chosen first because it's explicitly detailing what fields on the class to match.

However, in your case it's somewhat problematic. To support this, I've added a behavior selector at the JsonViewModule level and the JsonView level. It will default to the current behavior (CLASS_FIRST), but you can optionally set it to PATH_FIRST which should do what you want.

Check out the test case for this: https://github.com/monitorjbl/json-view/blob/master/json-view/src/test/java/com/monitorjbl/json/JsonViewSerializerTest.java#L868.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants