ããããJavaã®äžçã®æ°äººãå¿ ãããç解ããŠããªããžã§ããªãã¯ã®è€éãã®ããã€ãã説æããããšããå§ããŸãã çµéšè±å¯ãªéçºè ã®å Žåãæåã®2ã€ã®ãã€ã³ããèªãããšã¯ã§ããŸããã
1ïŒã¯ã€ã«ãã«ãŒããæ¡åŒµãã¹ãŒããŒãå¿ èŠãªçç±
ã¯ã€ã«ãã«ãŒãïŒïŒïŒã¯ããžã§ããªãã¯ã¯ã©ã¹ã«çœ®ãæãããšãã«äœ¿çšãããŸãã ã€ãŸãããã©ã¡ãŒã¿ãŒåãããåãäœã§ãããã¯é¢ä¿ãããŸããããŸããã¯ã€ã«ãã«ãŒããsuperããŒã¯ãŒããšextendããŒã¯ãŒããšçµã¿åãããŠäœ¿çšââããå Žåããã©ã¡ãŒã¿ãŒåãããåã芪ã§ãããç¹å®ã®ã¯ã©ã¹ãæ¡åŒµããããšãéèŠã§ãã ãããå®éã«ã©ã®ããã«äœ¿çšãããŠãããã®æ確ãªäŸã瀺ããŸãã
public void foobar(Map<String, Object> ms) { ... }
Map <StringãNumber>åã®å€æ°ãã¡ãœããã«æž¡ãããå ŽåãäœãããŸããããŸããïŒçç±-次ã®æ®µèœã§èª¬æããŸãïŒããã¡ãœããããã®ããã«å®£èšãããŠããã°æåããŸãã
public void foobar(Map<String, ?> ms) { ... }
ã€ãŸãã2çªç®ã®ã±ãŒã¹ã§ã¯ããããã«å€ãã©ã®ã¿ã€ãã«ãããã¯åé¡ã§ã¯ãªããšããäºå®ã«ã€ããŠè©±ããŠããŸãã ãããããããå¶éã課ããŸãããããå€ã§ã®ã¿Objectã¯ã©ã¹ã®ã¡ãœãããåŒã³åºãããšãã§ããŸãã ã¯ã©ã¹Numberã®ãªããžã§ã¯ãã®ã¿ããã®ãããã®å€ã«ãªãåŸãããšãããã£ãŠããå Žåããã®ããã«ã¡ãœããã®ã·ã°ããã£ãæžãæããããšãã§ããŸãã
public void foobar(Map<String, ? extends Number> ms) { ... }
ããã§ãMapå€ã«ã€ããŠãNumberã¯ã©ã¹ã®ã¡ãœããã䜿çšã§ããŸãã çåãçããŸããããªãããŒã¯ãŒãsuperãå¿ èŠãªã®ã§ããïŒ ãã©ã¡ãŒã¿ãŒåãããåã¯ç¹å®ã®ã¯ã©ã¹ã®èŠªã«ãªããšèšãããŠããŸãããããã¯ããªã¢ãŒãã£ãºã ãèš±å¯ããŸãã-ãã¹ãŠã®ã¯ã©ã¹ãé€ããã¹ãŠã®ã¯ã©ã¹ã®ã¡ãœãããåŒã³åºã-ãªããžã§ã¯ãã ããäžåºŠäŸãæããŸãã
List<? extends Number> list = new ArrayList<Number>(); List<? extends Number> list = new ArrayList<Integer>(); List<? extends Number> list = new ArrayList<Double>();
IntegerãšDoubleã®äž¡æ¹ãNumberããç¶æ¿ãããããã3ã€ã®å®£èšã¯ãã¹ãŠæå¹ã§ãã 3ã€ã®ãããã®å Žåã§ãããªã¹ãããNumberããåç §åã®å€æ°ãååŸãããã®ã¯ã©ã¹ã®ã¡ãœãããåŒã³åºãããšãã§ããŸãã ãã1ã€ã¯ãæåã®ã±ãŒã¹ã§ã¯ããã®ãªã³ã¯ã«Numberãšãã®çžç¶äººã2çªç®ã®Inegerãšãã®çžç¶äººã3çªç®ã®Doubleãšãã®çžç¶äººãå«ãŸããããšã§ãã ãããŠä»ãããªãã¯ãã®å®£èšã§ãªã¹ãã«äœãæžãããšãã§ãããšæããŸããïŒ ããªããçããå Žå-æ°ãšãã®çžç¶äººãããªãã¯ééã£ãŠããŸããã çãã¯äœããªãïŒ ãã®çç±ã¯ããã®ããã«å®£èšãããã·ãŒãã¯ãå®éã«ã¯Numberã·ãŒããŸãã¯IntegerãDoubleã·ãŒããããã³Numberã®åå«ã®ããããã§ããå¯èœæ§ãããããã§ãã superããŒã¯ãŒãã䜿çšããŠç¶æ³ãèæ ®ããŠãã ããã
List<? super Integer> list = new ArrayList<Integer>(); List<? super Integer> list = new ArrayList<Number>(); List<? super Integer> list = new ArrayList<Object>();
ãã®ãããªç¶æ³ã§ã¯ããã¹ãŠãæ£å察ã§ãã åãã£ã¹ããè¡ããªãå Žåãã·ãŒãããã®å€ã¯Objectåã®åç §å€æ°ã«ã®ã¿å²ãåœãŠãããšãã§ããŸãããã·ãŒããžã®æžã蟌ã¿ã¯Integeråã®ãã¹ãŠã®åå«ã§å©çšã§ããŸãã
2ïŒ
ãªã¹ã<çªå·>ãªã¹ã=æ°ããArrayList <æŽæ°>ïŒïŒãããïŒ ãªãïŒïŒ
æã ãç¹ã«ãµãŒãããŒãã£ã®ã©ã€ãã©ãªã䜿çšããŠããå ŽåïŒããã¯JasperReportsã©ã€ãã©ãªã§ããèµ·ãããŸããïŒãç§ã®æããã®ãããªå²ãåœãŠãè¡ãã®ã«èŠåŽããŸãã ãããŠãã³ã³ãã€ã©ããããåéããããšãæåŠãããšãæ£ããrightããããã«é«ãŸããŸãã åé¡ã¯äœã§ããïŒ ãªãã§ïŒ ããªã¢ãŒãã£ãºã ïŒ çµå±ã®ãšãããå®éã«åé¡ã¯äœã§ããïŒ æŽæ°ã¯ãŒã¯ã·ãŒãã¯ãæ°å€ã·ãŒããžã®åç §å€æ°ã«æžã蟌ãŸããæŽæ°ã¯æ°å€åã®çŽæ¥ã®åå«ã§ããããã®ãã¹ãŠã®ã¡ãœããã«ã¢ã¯ã»ã¹ã§ããŸãããããã£ãŠãã³ã¬ã¯ã·ã§ã³ããèŠçŽ ãåãåã£ãŠãåé¡ã¯ãããŸããã ãããããããã¯çºçããŸããã¹ãŒããŒããŒã¯ãŒãã«ã€ããŠæ³šææ·±ãèªãã å Žåããã®çç±ããã§ã«ç解ããŠããã¯ãã§ãã
äžçªäžã®è¡ã¯ãæ°å€ã·ãŒããšæŽæ°ã·ãŒãããŸã ç°ãªããªããžã§ã¯ãã§ããããšã§ãã Numberã·ãŒãã¯ãNumberïŒãããã£ãŠDoubleãFloatãªã©ïŒãæžã蟌ãããšãæå³ããŸãããã¡ãããIntegerã·ãŒãã¯ãããè¡ãã¹ãã§ã¯ãããŸããã
ãããã圌ããèšãããã«ãããªããæ¬åœã«æããªããããªãã¯ããªããã§ããªãããšãããããšãã§ããŸãïŒ
List<Number> list = (List)new ArrayList<Integer>();
ã€ãŸããå ã®ã·ãŒãã®ã¿ã€ãã«é¢ããæ å ±ãæ¶å»ããã ãã§ããããããçãã¿ã€ãã®ã¯ã©ã¹ãåãåããŸãããããã¯ããã§ã«äœã«ã§ãå²ãåœãŠãããšãã§ããŸãã ãã®ãããªããªãã¯ãè¡ãããšã¯ãå§ãã§ããŸããã
3ïŒGenericãšSpringïŒãŸãã¯ãã€ã³ã¿ãŒãã§ãŒã¹ãæ¶å»ããå¿ èŠãããçç±ïŒïŒ
æãèå³æ·±ããã®ã«å°éããŸããã ãã®åé¡ã¯ããžã§ããªãã¯åã«çŽæ¥é¢ä¿ãããã®ã§ã¯ãããŸããããããããéãã¹ã¿ã€ã«ãåå ã§ãã ããã€ãã®ã¯ã©ã¹ãæ€èšããŠãã ããã
@MappedSuperclass public abstract class BaseLinkEntity<S extends BaseEntity, T extends BaseEntity> extends BaseAuditableEntity { @JoinColumn(name = "SOURCE_ID", nullable = false) @ManyToOne(fetch = FetchType.LAZY) @JsonInclude(JsonInclude.Include.NON_EMPTY) protected S source; @JoinColumn(name = "TARGET_ID", nullable = false) @ManyToOne(fetch = FetchType.LAZY) @JsonInclude(JsonInclude.Include.NON_EMPTY) protected T target; } public interface LinkService<L extends BaseLinkEntity>{ List<L> getAllBySourceId(UUID id); List<L> getAllByTargetId(UUID id); } public abstract class BaseLinkService<L extends BaseLinkEntity> implements LinkReportService<L> { protected BaseLinkRepository<L> linkRepository; @Required public void setLinkRepository(BaseLinkRepository<L> linkRepository) { this.linkRepository = linkRepository; } @Override @Transactional(readOnly = true) public List<L> getAllBySourceId(UUID id) { return linkRepository.findBySourceId(id); } @Override @Transactional(readOnly = true) public List<L> getAllByTargetId(UUID id) { return linkRepository.findByTargetId(id); } } public class CardLinkServiceImpl extends BaseLinkReportService<CardLink> { @Override @Autowired @Qualifier("cardLinkReportRepository") public void setLinkRepository(BaseLinkRepository<CardLink> linkRepository) { super.setLinkRepository(linkRepository); } } public class MyClass{ @Autowired private LinkService<CardLink> cardLinkServiceImpl; }
ã»ãŒæšæºã®ã¹ããªã³ã°ã¢ãããŒãïŒäžéããŒã¹ã¯ã©ã¹ãé€ãïŒã¯ãã€ã³ã¿ãŒãã§ã€ã¹å®è£ ãã³ãã«ã§ãã ããã¯ããšã³ãã£ãã£ãå€å¯Ÿå€ã®é¢ä¿ã§æ¥ç¶ãããŠããããŒã¿ããŒã¹å ã®ããŒãã«ãæäœããããã«äœæãããŸããã ãããŠããã¹ãŠãããŸãããããã§ãã ããããããã§ã¯ãCardLinkServiceImplã§ãããã®ãªã³ã¯ã®ç¹å®ã®ã¡ãœãããããã€ãä¿®æ£ããå¿ èŠããããŸããã äžéã€ã³ã¿ãŒãã§ã€ã¹ãäœæããªãããã«ãæåã«ããããçŽæ¥CardLinkServiceImplã«è¿œå ããé©åãªå Žæã®ã¯ã©ã¹ã§ãããæ¶å»ããããšã«ããŸããã çµè«ïŒã³ã³ããå ã®ãã³ãèŠã€ãããŸããã§ããã
ã€ã³ã¿ãŒãããäžã§å°ã調ã¹ããšããããã®åäœã®çç±ãèŠã€ãããŸããã ãŸããSpring 3ã¯ã¯ã©ã¹ããžã§ããªãã¯ã§ã©ããããæ¹æ³ãç¥ããŸãããããããžã§ã¯ãã§ã¯Spring 4thããŒãžã§ã³ã䜿çšãããŸããã 2çªç®ã®çç±ã¯ãæ¥ã«ã¯ãã³ã³ããã«ã¹ããŒããã¯ã©ã¹ã®ãããã·ãäœæãããããšãå€ãããã§ãã
Springã¯AOPã䜿çšããŸã-å€ãã®å Žæã§ã¢ã¹ãã¯ãæåããã°ã©ãã³ã° ãã®ã¢ãããŒãã§ã¯ãäžéšã®ããžãã¯ã¯ã¡ãœããã«çŽæ¥å®è£ ãããŠããŸããããæ¥ã«aopã®ããŒã«ã䜿çšããŠãã³ã°ã¢ããããŸãã ãã®ã¢ãããŒããäœã¬ãã«ã§å®è£ ãããããã©ã³ã¿ã€ã ã®ã¹ããªã³ã°ã¯ã¯ã©ã¹ã®ãã€ãã³ãŒããå€æŽããå¿ èŠãªããžãã¯ãã¯ã©ã¹ã«è¿œå ããå ã®ãªããžã§ã¯ãã«é¢ããæ å ±ãæ¶å»ãããããã·ãªããžã§ã¯ããäœæããŸããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«é¢ããæ å ±ã¯æ®ããŸãã
ãã®å Žåãããã§aopã䜿çšããŠãã©ã³ã¶ã¯ã·ã§ã³ã管çããŸãïŒ@Transactionalã¢ãããŒã·ã§ã³ïŒã ãã®çµæãç¹å®ã®ã¡ãœãããå¥ã®ã€ã³ã¿ãŒãã§ã€ã¹ã«è»¢éããŠããã§ã«æ¶å»ããå¿ èŠããããŸããã
4ïŒæ±çšããã³Hibernate 5.2.1
ãããŠä»ãåé¡ã¯Hibernateã«ãããŸããããã¯3çªç®ã®æ®µèœã§èª¬æãããã®ãšäŒŒãŠããŸããããã°ã®ããã«èŠããŸãã ã³ãŒãã®ãããïŒ
public class Card{ @JoinColumn(name = "KIND_ID") @ManyToOne(fetch = FetchType.LAZY) protected DocumentKind documentKind; // BaseEntity, Id } public class CardLink extends BaseLinkEntity<Card, Card>{ } @NoRepositoryBean public interface BaseLinkRepository<T extends BaseLinkEntity> extends JpaRepository<T, UUID>, JpaSpecificationExecutor<T> { Page<T> findBySourceId(UUID sourceId, Pageable pageRequest); Page<T> findByTargetId(UUID targetId, Pageable pageRequest); } public interface CardLinkReportRepository extends BaseLinkRepository<CardLink>{ List<CardLink> findByTargetDocumentKindId(UUID documentKindId); }
hibernateã¯documentKindããããã£ãèŠã€ããããšãã§ããªããããSpringã¯CardLinkReportRepositoryã®å®è£ ãäœæã§ããŸããã å®éã圌ã¯ééã£ããªããžã§ã¯ãã§åœŒãæ¢ããŸãã äœãäœã§ããããç解ããããã«ãç§ã¯é·ãéãããã°ããäŒæ¢ç¶æ ã®ãœãŒã¹ã³ãŒãã調ã¹ãªããã°ãªããŸããã§ããã äžè¬åãããåãæäœããæ©èœãçµã¿èŸŒãŸããŠããããšãããããŸãããäœããã®åœ¢ã§æ²ãã£ãŠå®è£ ãããŸããã æ¬è³ªãç°¡åã«èª¬æããããšããŸãããããããç解ããã«ã¯ãMetamodelImplã¯ã©ã¹ãèªåã§æ¢çŽ¢ã§ããŸãïŒbuildMetamodelã¡ãœããïŒIterator persistentClassesãSet mappedSuperclassesãSessionFactoryImplementor sessionFactoryãboolean ignoreUnsuppentententonclassïŒããŒã¹ãã¯ãã£ãïŒãpersistentContextClassãPersistentcontextãPersistentãClassContextã AttributeFactoryïŒbuildAttributeã¡ãœããïŒAbstractManagedType ownerTypeãPropertyããããã£ïŒïŒã
ã¡ã¿ã¢ãã«ãæ§ç¯ãããšããHibernateã¯æåã«ãã¹ãŠã®ã¯ã©ã¹ãããã«æ§ç¯ãïŒbuildEntityïŒããã®åŸã§ã¡ãœããmethod-buildAttributeã®ãšã³ãã£ãã£ã«å±æ§ãæžã蟌ã¿ãŸãïŒã¯ã©ã¹ã®ã¢ãããžãŒ-ãã£ãŒã«ãïŒã å®éãBaseLinkEntityãªããžã§ã¯ãã®ã¡ã¿ã¢ãã«ã®ãšã³ãã£ãã£ã¯åäžã®ã€ã³ã¹ã¿ã³ã¹ã§äœæãããç¹å®ã®ã¿ã€ãã®å±æ§ïŒãžã§ããªãã¯ãã£ãŒã«ãïŒã¯buildAttributeã¡ãœããã§1åã ãå®çŸ©ãããŸãã 次ã«ããªããžããªã®JPAã¡ãœãããdocumentKindãã£ãŒã«ããæ€çŽ¢ãããšãã«ãå±æ§ã®æ§ç¯æã«æ¿å ¥ãããã¯ã©ã¹å ã®ãã£ãŒã«ããæ€çŽ¢ããŸãã åèªäœã¯ãç§ããã¯ãç解ããããšãã§ããªãã£ãã³ã³ããã¹ãïŒã©ãã§ãã©ã®æç¹ã§äœæããããïŒããååŸãããŸãã ãã®ãããBaseLinkEntityãã£ãŒã«ãã§æ€çŽ¢ã§ããŸãããç¹å®ã®ãžã§ããªãã¯ã¿ã€ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã»ããå šäœãã1ã€ã®ãšã³ãã£ãã£ã®ã¿ãæ€çŽ¢ã§ããŸãã
æãèå³æ·±ãïŒãããŠä»ã®ãšããç§ã«ã¯ç解ã§ããªãïŒããšã¯ããã®æ¹æ³ã§æžãçŽãã°ããã¹ãŠãæ©èœããããšã§ãã
@Query("SELECT link FROM CardLink link WHERE link.target.documentKind.id = ?1") public interface CardLinkReportRepository extends BaseLinkRepository<CardLink>{ List<CardLink> findByTargetDocumentKindId(UUID documentKindId); }