Java จัดการกับ XML และ JPA Annotated Classes

Sep 14 2020

ฉันใช้ xjc เพื่อรวบรวมไฟล์ XSD ไปยัง Java Classes และต้องการแก้ไข / ขยายเพื่อให้สามารถคงอยู่ได้ผ่าน JPA

ฉันคิดไม่ออกว่า "Coupling?" ที่ดีที่สุดคืออะไร จะเป็นอย่างไรและจะจัดระเบียบอย่างไรถ้าฉันแก้ไขคลาสที่คอมไพล์ xjc ให้คงอยู่ได้ฉันจะสูญเสียความสามารถในการคอมไพล์ XSD ใหม่หากมีการเปลี่ยนแปลงใด ๆ

แม้ว่าฉันจะไม่จำเป็นต้องคอมไพล์ใหม่ แต่ในบางกรณีฉันก็ยังไม่สามารถทำให้เป็นอนุกรม / deserialize ข้อมูลที่รวบรวมก่อนที่สคีมาของฉันจะเปลี่ยนไปได้

ฉันไม่ต้องการ "แยก" โดยสิ้นเชิงเนื่องจากฉันต้องการคงความสามารถในการคงอยู่ของวัตถุ XML ที่นำเข้าด้วยโค้ดเพียงไม่กี่บรรทัด (ไม่ต้องเขียน "ตัวแปลง" สำหรับแต่ละเอนทิตี XML)

มีใครเผชิญกับปัญหาเดียวกันนี้หรือไม่? คุณจัดการแก้ปัญหาอย่างไร

คำตอบ

JohannesHahn Sep 14 2020 at 22:08

ฉันคิดว่าปัญหาใหญ่ที่สุดที่คุณกำลังเผชิญอยู่ที่นี่คือสำหรับชั้นเรียนที่ต้อง "มองเห็น" กับบางสิ่งที่อยู่นอกโค้ดของคุณสิ่งสำคัญคือต้องมีแหล่งความจริงเพียงแหล่งเดียวสำหรับสิ่งที่นับเป็นข้อมูลที่ถูกต้อง มิฉะนั้นคุณจะต้องใช้เวลาทำงานไม่รู้จบในการซิงค์คำจำกัดความมากมายและการนำไปใช้งาน ข้อมูลจำเพาะไม่ตรงกัน (หรือไม่ซิงค์เมื่อเวลาผ่านไป) หรือตัวแปลงไม่เข้ากันกับข้อกำหนดเวอร์ชันล่าสุดเป็นต้นในกรณีของคุณทั้งสองคลาสจะปรากฏให้เห็น

  • สิ่งใดก็ตามที่สร้าง / บริโภคข้อมูล XML ที่แปลงเป็น / จากคลาส Java
  • และไปยังฐานข้อมูลที่อยู่เบื้องหลัง JPA ซึ่งกำหนดประเภทและข้อกำหนดด้านความสมบูรณ์ของข้อมูลลงในข้อมูลของคุณ

แนวทางของคุณตกอยู่ในอันตรายที่จะละเมิดหลักการสำคัญนี้หากคุณไม่ระมัดระวัง ทั้ง XSD เป็นแหล่งที่มาของความจริงหรือ JPA-ความหมายหรือสิ่งอื่นทั้งหมดเป็น แต่ตามหลักการนี้ n-1 ของ n คำจำกัดความได้จะขึ้นอยู่กับ n-TH

แล้วทางออกคืออะไร? และเช่นเคยขึ้นอยู่กับสิ่งที่คุณต้องการทำ

  1. อาจจะมีคลาสไม่มากนักและอาจจะไม่เคยเปลี่ยนหรือเปลี่ยนแค่น้อยมากและไม่บ่อยนัก ในกรณีนี้คุณอาจตัดสินใจยอมรับต้นทุนของการมีแหล่งความจริงสองแหล่ง

    คุณจะทำอย่างไร? ดังที่คุณได้กล่าวไปแล้วการแก้ไขโค้ดที่สร้างขึ้นโดยอัตโนมัตินั้นเปราะบางมาก นอกจากนี้ยังไม่จำเป็นต้องทำงานอย่างเข้มข้นเพื่อแยกชั้นเรียน (ย่อย) สำหรับคำอธิบายประกอบ JPA เท่านั้นเนื่องจากจะต้องใช้รหัสแผ่นหม้อไอน้ำจำนวนมากสำหรับตัวแปลง โชคดีที่ JPA Spec อนุญาตให้มีการกำหนดค่า XML ของการแมป ORM แทนการกำหนดค่าตามคำอธิบายประกอบตามปกติ ดูไฟล์orm.xml ด้วยวิธีนี้คุณสามารถกำหนดคลาสให้เป็นเอนทิตี JPA โดยไม่ต้องแก้ไขซอร์สโค้ดใด ๆ

  2. หาก XSD ของคุณเรียบง่ายเพียงพออาจเป็นไปได้ที่จะสร้างโครงสร้างฐานข้อมูลโดยตรงจาก XSD มีเครื่องมือสำหรับสิ่งนั้น นั่นไม่ได้ให้การแมป ORM แก่คุณ แต่ถ้า XSD ง่ายพอก็อาจสร้างไฟล์ orm.xml จาก XSD โดยอัตโนมัติได้เช่นกัน สิ่งนี้จะสร้าง XSD ขึ้นใหม่เป็นแหล่งความจริงเดียวของคุณ

  3. ถ้า 1. และ 2. ไม่ใช่ตัวเลือกสำหรับคุณเนื่องจากโครงสร้างข้อมูลของคุณซับซ้อนเกินไปอาจเป็นไปได้ที่จะมีข้อกำหนดที่สามที่สามารถทำหน้าที่เป็นแหล่งที่มาของความจริงสำหรับทั้งคู่และสามารถสร้างทั้ง XSD และ คำจำกัดความของ JPA ในบางรูปแบบ โดยหลักการแล้วคุณสามารถมีไฟล์ XML เสริมที่มีทั้ง XSD และนิยาม ORM รวมทั้ง XSLT ที่แยกสองครึ่ง (แน่นอนว่าคุณสามารถใช้ภาษาอื่น ๆ (meta-) แทน XML สำหรับข้อมูลจำเพาะหลักได้หากต้องการ) จากนั้นกระบวนการรวบรวมของคุณจะต้องมีขั้นตอนอื่นอยู่ข้างหน้า แต่ระวัง: ขึ้นอยู่กับความซับซ้อนในโครงสร้างข้อมูลของคุณซึ่งอาจทำให้เกิดการดีบัก / แก้ไขได้ยากหากจำเป็น

  4. คุณสามารถให้ Java Code เป็นแหล่งที่มาของความจริงและส่งออก XSD แทน แน่นอนคุณสามารถใช้การส่งออก JSON แทน XML ได้ง่ายกว่ามาก ฉันไม่คิดว่าจะเป็นไปได้มากเพราะ XSD มักจะได้รับจากข้อกำหนดภายนอกและไม่ได้สร้างขึ้นด้วยความตั้งใจ แต่เดี๋ยวก่อนคุณอาจเป็นข้อยกเว้นของกฎหรือไม่?

ไม่ว่าในกรณีใดคุณต้องทราบว่าจุดที่ละเอียดกว่าของ XML และ ORM เช่น JPA นั้นไม่จำเป็นต้องเข้ากันได้และความปรารถนาของคุณในการรวมกันอย่างสมบูรณ์อาจถึงวาระตั้งแต่เริ่มต้น อาจเป็นกรณีที่ข้อมูล XML บางส่วนของคุณไม่สามารถแปลงเป็นพื้นที่ฐานข้อมูลได้และในทางกลับกัน ตัวอย่างเช่นแนวคิดของธุรกรรมไม่มีอยู่ใน XML land JPA มีความรู้ (จำกัด ) เกี่ยวกับขั้นตอนการจัดเก็บทริกเกอร์ฐานข้อมูลและคุณสมบัติขั้นสูงอื่น ๆ (กึ่ง) ของฐานข้อมูล ฉันไม่รู้อะไรเลยในดินแดน XML ที่ค่อนข้างคล้ายกับสิ่งนั้น และในทางกลับกันไม่มีญาติสนิทของ XSLT ในฐานข้อมูล

ยิ่งไปกว่านั้น JPA อาจไม่มีประสิทธิภาพมากหากคุณจัดการกับข้อมูลจำนวนมาก บางครั้งมันเขียน SQL ที่น่ากลัวหากการกำหนดค่าของคุณไม่ได้รับการปรับให้เหมาะสม มันมีพฤติกรรมที่ไม่ตรงไปตรงมาอย่างสิ้นเชิงกับการทำธุรกรรมขี้เกียจโหลด ฯลฯ มันยอดเยี่ยมสำหรับการแยกรายละเอียดของฐานข้อมูลออกไป แต่เช่นเดียวกับสิ่งที่เป็นนามธรรมเช่นนี้อาจทำให้คุณเสียค่าใช้จ่ายหากคุณไม่รู้ ทำ. อาจเป็นไปไม่ได้เลยที่จะทำให้ประเด็นปลีกย่อยทั้งหมดถูกต้องเมื่อคุณปล่อยทุกอย่างไว้ที่เครื่องมืออัตโนมัติ

คุณควรคำนึงถึงสิ่งนี้เพื่อให้คุณสามารถจัดหาอินเทอร์เฟซที่ดีทั้งสำหรับการเพิ่มคุณสมบัติที่ขาดหายไปที่ปลายทั้งสองข้างและสำหรับการปรับแต่งการแมป