{"action":"created","issue":{"url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/13","repository_url":"https://api.github.com/repos/omnifaces/omnipersistence","labels_url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/13/labels{/name}","comments_url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/13/comments","events_url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/13/events","html_url":"https://github.com/omnifaces/omnipersistence/pull/13","id":316831912,"number":13,"title":"Added functionality for enhanced @Enumerated mapping.","user":{"login":"skuntsel","id":32160012,"avatar_url":"https://avatars0.githubusercontent.com/u/32160012?v=4","gravatar_id":"","url":"https://api.github.com/users/skuntsel","html_url":"https://github.com/skuntsel","followers_url":"https://api.github.com/users/skuntsel/followers","following_url":"https://api.github.com/users/skuntsel/following{/other_user}","gists_url":"https://api.github.com/users/skuntsel/gists{/gist_id}","starred_url":"https://api.github.com/users/skuntsel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skuntsel/subscriptions","organizations_url":"https://api.github.com/users/skuntsel/orgs","repos_url":"https://api.github.com/users/skuntsel/repos","events_url":"https://api.github.com/users/skuntsel/events{/privacy}","received_events_url":"https://api.github.com/users/skuntsel/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-04-23T14:15:04Z","updated_at":"2018-04-23T18:17:11Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/omnifaces/omnipersistence/pulls/13","html_url":"https://github.com/omnifaces/omnipersistence/pull/13","diff_url":"https://github.com/omnifaces/omnipersistence/pull/13.diff","patch_url":"https://github.com/omnifaces/omnipersistence/pull/13.patch"},"body":"Added basic functionality for enhanced enum mapping that empowers standard JPA `@Enumerated` mapping via `@JpaEnum` annotation.\r\n\r\nWhen used in conjunction with `@Enumerated(ORDINAL)` `@JpaEnum` allows developer to specify `fieldName` of type `Integer`/`int` of application enum that will be persisted to the database, instead of the standard `ordinal` of a particular enum.\r\n\r\nWhen used in conjunction with `@Enumerated(STRING)` `@JpaEnum` allows developer to specify `fieldName` of type `String` of application enum that will be persisted to the database, instead of the standard `name` of a particular enum.\r\n\r\nThis allows to create more robust applications with the ability to modify/add/delete enum instances during application development, thus alleviating the vulnerabilities of standard JPA `@Enumerated`.\r\n\r\nIts usage is as follows:\r\n\r\n    @JpaEnum(fieldName = \"id\")\r\n    public enum ProductStatus {\r\n    \r\n        IN_STOCK(1), OUT_OF_STOCK(10), DISCONTINUED(20);\r\n    \r\n        private int id;\r\n\r\n        private ProductStatus(int id) {\r\n            this.id = id;\r\n        }\r\n\r\n        public int getId() {\r\n            return id;\r\n        }\r\n\r\n    }\r\n\r\nand\r\n\r\n    @JpaEnum(type = EnumType.STRING, fieldName = \"code\")\r\n    public enum UserRole {\r\n    \r\n        USER(\"USR\"), EMPLOYEE(\"EMP\"), MANAGER(\"MGR\");\r\n    \r\n        private String code;\r\n\r\n        private UserRole(String code) {\r\n            this.code = code;\r\n        }\r\n\r\n        public String getCode() {\r\n            return code;\r\n        }\r\n    \r\n    }\r\n\r\nwith\r\n\r\n    @Entity\r\n    public class Product extends GeneratedIdEntity<Long> {\r\n\r\n        private static final long serialVersionUID = 1L;\r\n    \r\n        @Enumerated\r\n        private ProductStatus productStatus;\r\n\r\n        @ElementCollection\r\n        @Enumerated(STRING)\r\n        private Set<UserRole> userRoles = new HashSet<>();\r\n\r\n        public ProductStatus getProductStatus() {\r\n            return productStatus;\r\n        }\r\n\r\n        public void setProductStatus(ProductStatus productStatus) {\r\n            this.productStatus = productStatus;\r\n        }\r\n\r\n        public Set<UserRole> getUserRoles() {\r\n            return userRoles;\r\n        }\r\n\r\n        public void setUserRoles(Set<UserRole> userRoles) {\r\n            this.userRoles = userRoles;\r\n        }\r\n    \r\n        public void addUserRole(UserRole userRole) {\r\n            userRoles.add(userRole);\r\n        }\r\n\r\n    }\r\n\r\nWith such setup persistence provider will save to the database the status as either 1, 10 or 20 (as opposed to the default 0, 1 or 2 otherwise) and role as either USR, EMP or MGR (as opposed to default USER, EMPLOYEE or MANAGER otherwise).\r\n\r\nThis may be evolved even further with another, yet to be done, annotation `@JpaEnumSpecifics` that will define the correlation with the database lookup table for each enum used and will do, among others, the following:\r\n- issue warnings in case there is no one-to-one correlation between the enum class and the database table;\r\n- update database table basing on the current enum code, or update enum code basing on the database table;\r\n- create and fill in database tables."},"comment":{"url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/comments/383672518","html_url":"https://github.com/omnifaces/omnipersistence/pull/13#issuecomment-383672518","issue_url":"https://api.github.com/repos/omnifaces/omnipersistence/issues/13","id":383672518,"user":{"login":"skuntsel","id":32160012,"avatar_url":"https://avatars0.githubusercontent.com/u/32160012?v=4","gravatar_id":"","url":"https://api.github.com/users/skuntsel","html_url":"https://github.com/skuntsel","followers_url":"https://api.github.com/users/skuntsel/followers","following_url":"https://api.github.com/users/skuntsel/following{/other_user}","gists_url":"https://api.github.com/users/skuntsel/gists{/gist_id}","starred_url":"https://api.github.com/users/skuntsel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skuntsel/subscriptions","organizations_url":"https://api.github.com/users/skuntsel/orgs","repos_url":"https://api.github.com/users/skuntsel/repos","events_url":"https://api.github.com/users/skuntsel/events{/privacy}","received_events_url":"https://api.github.com/users/skuntsel/received_events","type":"User","site_admin":false},"created_at":"2018-04-23T18:17:11Z","updated_at":"2018-04-23T18:17:11Z","author_association":"CONTRIBUTOR","body":"That sounds really good! It was definitely intended to serve as a working\ntitle, as I didn’t have much chance to contemplate about its name.\nUntil we have first class support for such functionality from the spec this\nis our best bet. It puzzles me, though, why it hasn’t yet paved its way\ninto the specification.\nWe also need to add extra annotation (nested or top-level) to control\ncorrespondence with the database. It would feel natural to either map the\ndatabase table as a source for enum values, or, preferrably, reflect\nchanges in enum code in the database table.\n\nпн, 23 апр. 2018 г. в 21:02, Bauke Scholtz <notifications@github.com>:\n\n> Great addition. I'm only a bit torn on the name @JpaEnum.\n>\n> How about @EnumMapping?\n>\n> —\n> You are receiving this because you authored the thread.\n> Reply to this email directly, view it on GitHub\n> <https://github.com/omnifaces/omnipersistence/pull/13#issuecomment-383668080>,\n> or mute the thread\n> <https://github.com/notifications/unsubscribe-auth/Aeq5DGauSTsfi4BVzj2m86IQDEDdHqWgks5trhdKgaJpZM4Tf-me>\n> .\n>\n-- \n\nС уважением,\nКюнтцель Сергей\n"}}
{"actor":{"display_login":"skuntsel"}}