{"action":"closed","number":1443,"pull_request":{"url":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443","id":39465399,"html_url":"https://github.com/ModeShape/modeshape/pull/1443","diff_url":"https://github.com/ModeShape/modeshape/pull/1443.diff","patch_url":"https://github.com/ModeShape/modeshape/pull/1443.patch","issue_url":"https://api.github.com/repos/ModeShape/modeshape/issues/1443","number":1443,"state":"closed","locked":false,"title":"Fix MODE-2490","user":{"login":"jasperstein","id":3168837,"avatar_url":"https://avatars.githubusercontent.com/u/3168837?v=3","gravatar_id":"","url":"https://api.github.com/users/jasperstein","html_url":"https://github.com/jasperstein","followers_url":"https://api.github.com/users/jasperstein/followers","following_url":"https://api.github.com/users/jasperstein/following{/other_user}","gists_url":"https://api.github.com/users/jasperstein/gists{/gist_id}","starred_url":"https://api.github.com/users/jasperstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasperstein/subscriptions","organizations_url":"https://api.github.com/users/jasperstein/orgs","repos_url":"https://api.github.com/users/jasperstein/repos","events_url":"https://api.github.com/users/jasperstein/events{/privacy}","received_events_url":"https://api.github.com/users/jasperstein/received_events","type":"User","site_admin":false},"body":"ORDER BY col1, col2 used to cause a NullPointerException whenever col1 or col2 were nullable and indeed did contain null values. This is because the row's col1 and col2 were being serialized as a tuple, and the serialization (correctly) assumed that since a tuple was created, the sort key was non-null. However serialization of the tuple was done by serializing each component, and they +can+ be null.\r\n\r\nTherefore, the component serializers should use a null-safe wrapper around the original serializer, see their various getSerializer() implementations. The wrapper itself is in lines 585-615. Since I guess we don't always know what serializers we have, and some serializers also leave not enough wiggle room to accomodate NULLs without violating all kinds of contracts, we have to have (unfortunately) an extra sentinel boolean to indicate a null value (if set to false, lines 594-595 and 605).\r\n\r\nThe Tuples class holds a WeakHashMap to store the wrappers (line 617) so the same wrapper will be retrieved when requested multiple times. Perhaps there's a better way/place to store them; I am currently too unfamiliar with ModeShape to know. (Maybe inside the Serializers class?) By using a WeakHashMap I ensure that the wrappers will be removed whenever the bufferManager gets garbage-collected.\r\n\r\nWhenever a null-safe serializer is requested, it is first retrieved from the WeakHashMap if available. If not, it is first checked whether the original serializer from the bufferManager is null-safe. If so, no wrapping is done and the original serializer is used.\r\n\r\nYours,\r\nJasper Stein (XebiaLabs)","created_at":"2015-07-08T11:06:20Z","updated_at":"2015-07-16T13:19:58Z","closed_at":"2015-07-16T13:19:58Z","merged_at":"2015-07-16T13:19:58Z","merge_commit_sha":"8f332111ad64dcf9cde48da7c1c9b493c266f935","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443/commits","review_comments_url":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443/comments","review_comment_url":"https://api.github.com/repos/ModeShape/modeshape/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ModeShape/modeshape/issues/1443/comments","statuses_url":"https://api.github.com/repos/ModeShape/modeshape/statuses/9e99a9cbb816dbf866810f76ed6dd1771fb59c29","head":{"label":"jasperstein:MODE-2490","ref":"MODE-2490","sha":"9e99a9cbb816dbf866810f76ed6dd1771fb59c29","user":{"login":"jasperstein","id":3168837,"avatar_url":"https://avatars.githubusercontent.com/u/3168837?v=3","gravatar_id":"","url":"https://api.github.com/users/jasperstein","html_url":"https://github.com/jasperstein","followers_url":"https://api.github.com/users/jasperstein/followers","following_url":"https://api.github.com/users/jasperstein/following{/other_user}","gists_url":"https://api.github.com/users/jasperstein/gists{/gist_id}","starred_url":"https://api.github.com/users/jasperstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasperstein/subscriptions","organizations_url":"https://api.github.com/users/jasperstein/orgs","repos_url":"https://api.github.com/users/jasperstein/repos","events_url":"https://api.github.com/users/jasperstein/events{/privacy}","received_events_url":"https://api.github.com/users/jasperstein/received_events","type":"User","site_admin":false},"repo":{"id":38681814,"name":"modeshape","full_name":"jasperstein/modeshape","owner":{"login":"jasperstein","id":3168837,"avatar_url":"https://avatars.githubusercontent.com/u/3168837?v=3","gravatar_id":"","url":"https://api.github.com/users/jasperstein","html_url":"https://github.com/jasperstein","followers_url":"https://api.github.com/users/jasperstein/followers","following_url":"https://api.github.com/users/jasperstein/following{/other_user}","gists_url":"https://api.github.com/users/jasperstein/gists{/gist_id}","starred_url":"https://api.github.com/users/jasperstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jasperstein/subscriptions","organizations_url":"https://api.github.com/users/jasperstein/orgs","repos_url":"https://api.github.com/users/jasperstein/repos","events_url":"https://api.github.com/users/jasperstein/events{/privacy}","received_events_url":"https://api.github.com/users/jasperstein/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jasperstein/modeshape","description":"ModeShape is a distributed, hierarchical, transactional, and consistent data store with support for queries, full-text search, events, versioning, references, and flexible and dynamic schemas. It is very fast, highly available, extremely scalable, and it is 100% open source and written in Java. Clients use the JSR-283 standard Java API for content repositories (aka, JCR) or ModeShape's REST API, and can query content through JDBC and SQL.","fork":true,"url":"https://api.github.com/repos/jasperstein/modeshape","forks_url":"https://api.github.com/repos/jasperstein/modeshape/forks","keys_url":"https://api.github.com/repos/jasperstein/modeshape/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jasperstein/modeshape/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jasperstein/modeshape/teams","hooks_url":"https://api.github.com/repos/jasperstein/modeshape/hooks","issue_events_url":"https://api.github.com/repos/jasperstein/modeshape/issues/events{/number}","events_url":"https://api.github.com/repos/jasperstein/modeshape/events","assignees_url":"https://api.github.com/repos/jasperstein/modeshape/assignees{/user}","branches_url":"https://api.github.com/repos/jasperstein/modeshape/branches{/branch}","tags_url":"https://api.github.com/repos/jasperstein/modeshape/tags","blobs_url":"https://api.github.com/repos/jasperstein/modeshape/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jasperstein/modeshape/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jasperstein/modeshape/git/refs{/sha}","trees_url":"https://api.github.com/repos/jasperstein/modeshape/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jasperstein/modeshape/statuses/{sha}","languages_url":"https://api.github.com/repos/jasperstein/modeshape/languages","stargazers_url":"https://api.github.com/repos/jasperstein/modeshape/stargazers","contributors_url":"https://api.github.com/repos/jasperstein/modeshape/contributors","subscribers_url":"https://api.github.com/repos/jasperstein/modeshape/subscribers","subscription_url":"https://api.github.com/repos/jasperstein/modeshape/subscription","commits_url":"https://api.github.com/repos/jasperstein/modeshape/commits{/sha}","git_commits_url":"https://api.github.com/repos/jasperstein/modeshape/git/commits{/sha}","comments_url":"https://api.github.com/repos/jasperstein/modeshape/comments{/number}","issue_comment_url":"https://api.github.com/repos/jasperstein/modeshape/issues/comments{/number}","contents_url":"https://api.github.com/repos/jasperstein/modeshape/contents/{+path}","compare_url":"https://api.github.com/repos/jasperstein/modeshape/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jasperstein/modeshape/merges","archive_url":"https://api.github.com/repos/jasperstein/modeshape/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jasperstein/modeshape/downloads","issues_url":"https://api.github.com/repos/jasperstein/modeshape/issues{/number}","pulls_url":"https://api.github.com/repos/jasperstein/modeshape/pulls{/number}","milestones_url":"https://api.github.com/repos/jasperstein/modeshape/milestones{/number}","notifications_url":"https://api.github.com/repos/jasperstein/modeshape/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jasperstein/modeshape/labels{/name}","releases_url":"https://api.github.com/repos/jasperstein/modeshape/releases{/id}","created_at":"2015-07-07T10:52:42Z","updated_at":"2015-07-07T10:52:52Z","pushed_at":"2015-07-16T08:01:47Z","git_url":"git://github.com/jasperstein/modeshape.git","ssh_url":"git@github.com:jasperstein/modeshape.git","clone_url":"https://github.com/jasperstein/modeshape.git","svn_url":"https://github.com/jasperstein/modeshape","homepage":"http://www.modeshape.org","size":122403,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ModeShape:master","ref":"master","sha":"6b79e2db1fd604d6b9fb03f79fa370a0a5e5a6c9","user":{"login":"ModeShape","id":148023,"avatar_url":"https://avatars.githubusercontent.com/u/148023?v=3","gravatar_id":"","url":"https://api.github.com/users/ModeShape","html_url":"https://github.com/ModeShape","followers_url":"https://api.github.com/users/ModeShape/followers","following_url":"https://api.github.com/users/ModeShape/following{/other_user}","gists_url":"https://api.github.com/users/ModeShape/gists{/gist_id}","starred_url":"https://api.github.com/users/ModeShape/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ModeShape/subscriptions","organizations_url":"https://api.github.com/users/ModeShape/orgs","repos_url":"https://api.github.com/users/ModeShape/repos","events_url":"https://api.github.com/users/ModeShape/events{/privacy}","received_events_url":"https://api.github.com/users/ModeShape/received_events","type":"Organization","site_admin":false},"repo":{"id":1244027,"name":"modeshape","full_name":"ModeShape/modeshape","owner":{"login":"ModeShape","id":148023,"avatar_url":"https://avatars.githubusercontent.com/u/148023?v=3","gravatar_id":"","url":"https://api.github.com/users/ModeShape","html_url":"https://github.com/ModeShape","followers_url":"https://api.github.com/users/ModeShape/followers","following_url":"https://api.github.com/users/ModeShape/following{/other_user}","gists_url":"https://api.github.com/users/ModeShape/gists{/gist_id}","starred_url":"https://api.github.com/users/ModeShape/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ModeShape/subscriptions","organizations_url":"https://api.github.com/users/ModeShape/orgs","repos_url":"https://api.github.com/users/ModeShape/repos","events_url":"https://api.github.com/users/ModeShape/events{/privacy}","received_events_url":"https://api.github.com/users/ModeShape/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ModeShape/modeshape","description":"ModeShape is a distributed, hierarchical, transactional, and consistent data store with support for queries, full-text search, events, versioning, references, and flexible and dynamic schemas. It is very fast, highly available, extremely scalable, and it is 100% open source and written in Java. Clients use the JSR-283 standard Java API for content repositories (aka, JCR) or ModeShape's REST API, and can query content through JDBC and SQL.","fork":false,"url":"https://api.github.com/repos/ModeShape/modeshape","forks_url":"https://api.github.com/repos/ModeShape/modeshape/forks","keys_url":"https://api.github.com/repos/ModeShape/modeshape/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ModeShape/modeshape/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ModeShape/modeshape/teams","hooks_url":"https://api.github.com/repos/ModeShape/modeshape/hooks","issue_events_url":"https://api.github.com/repos/ModeShape/modeshape/issues/events{/number}","events_url":"https://api.github.com/repos/ModeShape/modeshape/events","assignees_url":"https://api.github.com/repos/ModeShape/modeshape/assignees{/user}","branches_url":"https://api.github.com/repos/ModeShape/modeshape/branches{/branch}","tags_url":"https://api.github.com/repos/ModeShape/modeshape/tags","blobs_url":"https://api.github.com/repos/ModeShape/modeshape/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ModeShape/modeshape/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ModeShape/modeshape/git/refs{/sha}","trees_url":"https://api.github.com/repos/ModeShape/modeshape/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ModeShape/modeshape/statuses/{sha}","languages_url":"https://api.github.com/repos/ModeShape/modeshape/languages","stargazers_url":"https://api.github.com/repos/ModeShape/modeshape/stargazers","contributors_url":"https://api.github.com/repos/ModeShape/modeshape/contributors","subscribers_url":"https://api.github.com/repos/ModeShape/modeshape/subscribers","subscription_url":"https://api.github.com/repos/ModeShape/modeshape/subscription","commits_url":"https://api.github.com/repos/ModeShape/modeshape/commits{/sha}","git_commits_url":"https://api.github.com/repos/ModeShape/modeshape/git/commits{/sha}","comments_url":"https://api.github.com/repos/ModeShape/modeshape/comments{/number}","issue_comment_url":"https://api.github.com/repos/ModeShape/modeshape/issues/comments{/number}","contents_url":"https://api.github.com/repos/ModeShape/modeshape/contents/{+path}","compare_url":"https://api.github.com/repos/ModeShape/modeshape/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ModeShape/modeshape/merges","archive_url":"https://api.github.com/repos/ModeShape/modeshape/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ModeShape/modeshape/downloads","issues_url":"https://api.github.com/repos/ModeShape/modeshape/issues{/number}","pulls_url":"https://api.github.com/repos/ModeShape/modeshape/pulls{/number}","milestones_url":"https://api.github.com/repos/ModeShape/modeshape/milestones{/number}","notifications_url":"https://api.github.com/repos/ModeShape/modeshape/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ModeShape/modeshape/labels{/name}","releases_url":"https://api.github.com/repos/ModeShape/modeshape/releases{/id}","created_at":"2011-01-12T02:30:46Z","updated_at":"2015-07-14T23:45:03Z","pushed_at":"2015-07-16T13:19:58Z","git_url":"git://github.com/ModeShape/modeshape.git","ssh_url":"git@github.com:ModeShape/modeshape.git","clone_url":"https://github.com/ModeShape/modeshape.git","svn_url":"https://github.com/ModeShape/modeshape","homepage":"http://www.modeshape.org","size":160127,"stargazers_count":138,"watchers_count":138,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":144,"mirror_url":null,"open_issues_count":0,"forks":144,"open_issues":0,"watchers":138,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443"},"html":{"href":"https://github.com/ModeShape/modeshape/pull/1443"},"issue":{"href":"https://api.github.com/repos/ModeShape/modeshape/issues/1443"},"comments":{"href":"https://api.github.com/repos/ModeShape/modeshape/issues/1443/comments"},"review_comments":{"href":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443/comments"},"review_comment":{"href":"https://api.github.com/repos/ModeShape/modeshape/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ModeShape/modeshape/pulls/1443/commits"},"statuses":{"href":"https://api.github.com/repos/ModeShape/modeshape/statuses/9e99a9cbb816dbf866810f76ed6dd1771fb59c29"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"hchiorean","id":995683,"avatar_url":"https://avatars.githubusercontent.com/u/995683?v=3","gravatar_id":"","url":"https://api.github.com/users/hchiorean","html_url":"https://github.com/hchiorean","followers_url":"https://api.github.com/users/hchiorean/followers","following_url":"https://api.github.com/users/hchiorean/following{/other_user}","gists_url":"https://api.github.com/users/hchiorean/gists{/gist_id}","starred_url":"https://api.github.com/users/hchiorean/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hchiorean/subscriptions","organizations_url":"https://api.github.com/users/hchiorean/orgs","repos_url":"https://api.github.com/users/hchiorean/repos","events_url":"https://api.github.com/users/hchiorean/events{/privacy}","received_events_url":"https://api.github.com/users/hchiorean/received_events","type":"User","site_admin":false},"comments":17,"review_comments":0,"commits":1,"additions":119,"deletions":27,"changed_files":4}}