Changes between Initial Version and Version 1 of P8


Ignore:
Timestamp:
06/06/26 14:11:50 (11 days ago)
Author:
216009
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • P8

    v1 v1  
     1= Advanced Application Development =
     2
     3== Transactions ==
     4=== Multi-Operation Transaction Documentation ===
     5In this application, transactional integrity guarantees that changes to entity profiles do not leave the schema with orphaned relational data. A prime example occurs when creating or updating a profile within ProfessorDAOImpl.java.
     6
     7Because a professor's university affiliation is stored across separate boundaries (Professor table and the affiliated reference bridge table), modifying a professor requires writing to multiple tables sequentially. If the primary details save successfully but the university bridge mapping breaks, the database would fall out of sync. To eliminate this risk, the application explicitly controls boundaries via connection.setAutoCommit(false), manually invoking a group .commit() only when all steps conclude, or a .rollback() if a query throws an error.
     8
     9Transactional Storage Implementation (ProfessorDAOImpl.java):
     10{{{
     11#!java
     12@Override
     13public void save(Professor professor) throws SQLException {
     14final String INSERT_PROF = "INSERT INTO Professor (name, surname, age, facultyid) VALUES (?, ?, ?, ?)";
     15final String INSERT_AFFILIATION = "INSERT INTO affiliated (university_id, professor_id) VALUES (?, ?)";
     16
     17try (Connection conn = JDBCUtils.getConnection()) {
     18    // Step 1: Initialize the manual transaction boundary
     19    conn.setAutoCommit(false);
     20   
     21    try (PreparedStatement ps = conn.prepareStatement(INSERT_PROF, Statement.RETURN_GENERATED_KEYS)) {
     22        ps.setString(1, professor.getName());
     23        ps.setString(2, professor.getSurname());
     24        ps.setInt(3, professor.getAge());
     25        ps.setLong(4, professor.getFacultyid());
     26        ps.executeUpdate();
     27
     28        // Fetch the primary key generated by the database
     29        ResultSet rs = ps.getGeneratedKeys();
     30        if (rs.next()) {
     31            long newProfId = rs.getLong(1);
     32
     33            // Step 2: Conditional execution dependent on primary table completion
     34            if (professor.getUniversity() != null && professor.getUniversity().getId() != null) {
     35                try (PreparedStatement psAff = conn.prepareStatement(INSERT_AFFILIATION)) {
     36                    psAff.setLong(1, professor.getUniversity().getId());
     37                    psAff.setLong(2, newProfId);
     38                    psAff.executeUpdate();
     39                }
     40            }
     41        }
     42        // Step 3: Atomic save across both tables simultaneously
     43        conn.commit();
     44    } catch (SQLException e) {
     45        // Step 4: Full structural rollback if any single operation fails
     46        conn.rollback();
     47        throw e;
     48    }
     49}
     50}
     51}}}
     52
     53Transactional Modification Implementation (ProfessorDAOImpl.java):
     54{{{
     55#!java
     56@Override
     57public void update(Professor professor) throws SQLException {
     58final String UPDATE_PROF = "UPDATE Professor SET name = ?, surname = ?, age = ?, facultyid = ? WHERE id = ?";
     59final String DELETE_AFFILIATION = "DELETE FROM affiliated WHERE professor_id = ?";
     60final String INSERT_AFFILIATION = "INSERT INTO affiliated (university_id, professor_id) VALUES (?, ?)";
     61
     62try (Connection conn = JDBCUtils.getConnection()) {
     63    // Clear auto-commit to prevent intermediate modifications from tracking
     64    conn.setAutoCommit(false);
     65    try {
     66        // Operation 1: Update core attributes
     67        try (PreparedStatement ps = conn.prepareStatement(UPDATE_PROF)) {
     68            ps.setString(1, professor.getName());
     69            ps.setString(2, professor.getSurname());
     70            ps.setInt(3, professor.getAge());
     71            ps.setLong(4, professor.getFacultyid());
     72            ps.setLong(5, professor.getId());
     73            ps.executeUpdate();
     74        }
     75
     76        // Operation 2: Flush out old relational mappings
     77        try (PreparedStatement psDel = conn.prepareStatement(DELETE_AFFILIATION)) {
     78            psDel.setLong(1, professor.getId());
     79            psDel.executeUpdate();
     80        }
     81
     82        // Operation 3: Re-insert active relational state mappings
     83        if (professor.getUniversity() != null && professor.getUniversity().getId() != null) {
     84            try (PreparedStatement psIns = conn.prepareStatement(INSERT_AFFILIATION)) {
     85                psIns.setLong(1, professor.getUniversity().getId());
     86                psIns.setLong(2, professor.getId());
     87                psIns.executeUpdate();
     88            }
     89        }
     90        // Finalize unit of work safely
     91        conn.commit();
     92    } catch (SQLException e) {
     93        // Roll back to the original database state if any query faults
     94        conn.rollback();
     95        throw e;
     96    }
     97}
     98}
     99}}}
     100
     101== Database Connection Pooling ==
     102=== Connection Setup Architecture ===
     103To handle database operations systematically, connection requests are routed through a singular provider method using the JDBCUtils.getConnection() structural pattern. Rather than instantiating hardcoded configuration attributes inside discrete controllers, the persistence layers pull a ready connection whenever a data action is initiated.
     104
     105Resource safety is ensured at the runtime level via Java's try-with-resources declaration structures. Because the code instantiates Connection objects directly within try blocks, the underlying connection context is explicitly guaranteed to drop closed the microsecond a query cycle finishes, allowing the database driver to process active connection lifecycles without bleeding socket leakage.
     106
     107=== Application Usage Examples ===
     108Below are standard methods highlighting how active database loops borrow a temporary connection resource context and immediately hand it back upon block termination.
     109
     110Aggregation Query Implementation Example (findAverageAgeByFaculty):
     111{{{
     112#!java
     113@Override
     114public Map<String, Double> findAverageAgeByFaculty() {
     115String query = "SELECT f.name as faculty_name, AVG(p.age) as average_age " +
     116"FROM professor p JOIN faculty f ON f.id = p.facultyid " +
     117"GROUP BY f.name";
     118Map<String, Double> result = new HashMap<>();
     119
     120// Establishing resource visibility block boundary
     121try (Connection connection = JDBCUtils.getConnection();
     122     PreparedStatement stmt = connection.prepareStatement(query)) {
     123    ResultSet rs = stmt.executeQuery();
     124    while (rs.next()) {
     125        result.put(rs.getString("faculty_name"), rs.getDouble("average_age"));
     126    }
     127} catch (SQLException e) {
     128    e.printStackTrace();
     129} // Connection implicitly closes right here, ensuring safe lifecycle recovery
     130return result;
     131}
     132}}}
     133
     134Relational Joining Fetch Implementation Example (findStudentsByUniversityId):
     135{{{
     136#!java
     137@Override
     138public List findStudentsByUniversityId(int universityId) {
     139String query = "SELECT s.id, s.name, s.surname, s.location, s.studentindex, s.facultyid " +
     140"FROM student s " +
     141"JOIN faculty f ON s.facultyid = f.id " +
     142"JOIN university u ON f.university_id = u.id " +
     143"WHERE u.id = ?";
     144List students = new ArrayList<>();
     145
     146// Requesting single connection endpoint from JDBCUtils factory
     147try (Connection conn = JDBCUtils.getConnection();
     148     PreparedStatement stmt = conn.prepareStatement(query)) {
     149    stmt.setInt(1, universityId);
     150    ResultSet rs = stmt.executeQuery();
     151    while (rs.next()) {
     152        students.add(new Student(
     153                rs.getLong("id"), rs.getString("name"), rs.getString("surname"),
     154                rs.getString("location"), rs.getInt("studentindex"), rs.getLong("facultyid")
     155        ));
     156    }
     157} catch (SQLException e) {
     158    throw new RuntimeException(e);
     159} // Lifecycle terminates cleanly, preventing connection exhaustion
     160return students;
     161}
     162}}}
     163
     164= Advanced Application Development AI Usage =
     165
     166Name of AI service/solution that was used: Gemini 3 Flash
     167
     168URL: https://gemini.google.com/
     169
     170Type of service/subscription: Free Tier
     171
     172Final result: I reviewed my completed Java application prototype with the AI assistant to analyze how my data layer handles multi-table consistency and resource lifecycles. This allowed me to formally document my existing transaction blocks and connection patterns to fulfill the Phase P8 submission requirements without altering my working codebase.
     173
     174Diagram:
     175
     176Results in details / description:
     177
     178Transaction Architecture Analysis: I had already built multi-table synchronization blocks into my ProfessorDAOImpl and FacultyDAOImpl classes to prevent orphan rows (such as managing the affiliated bridge table during updates, and handling professor dependencies during faculty deletion). I used the AI to review these sections to confirm they perfectly matched the criteria for formal multi-operation database transaction boundaries.
     179
     180Resource Management Breakdown: I used the AI to help me articulate how Java’s try-with-resources blocks interact with my custom JDBCUtils.getConnection() handler, ensuring that active connection sockets are safely closed and processed without any database resource leaks.
     181
     182Trac Syntax Verification: Because our course wiki utilizes specific formatting blocks ({{{ #!java ... }}}), I used the AI to convert my existing code snippets into perfectly structured markup so they render cleanly on the platform.
     183
     184Entire AI usage log:
     185
     186User: I have already finished writing my ProfessorDAOImpl.java and FacultyDAOImpl.java classes using plain JDBC. Can you look at my code and help me find the specific sections where I used transactions so I can document them for Phase P8?
     187
     188AI: Analyzed the provided classes and pointed out that the save() and update() methods in ProfessorDAOImpl and the delete() method in FacultyDAOImpl already implement complete manual transaction workflows. They explicitly turn off auto-commit, update multiple tables sequentially to preserve foreign key constraints, and use clean commit() and rollback() blocks.
     189
     190User: Perfect, I wrote those to stop the database from breaking. Now, how should I explain the connection infrastructure part since I am using my own JDBCUtils class instead of a third-party pooling library?
     191
     192AI: Recommended highlighting the centralized design pattern of your JDBCUtils factory. It suggested explaining how your use of modern Java try-with-resources blocks automatically closes connection lifecycles the moment a data query loop terminates, preventing connection exhaustion.
     193
     194User: Can you format these specific code snippets from my files into clean Trac Wiki markup blocks so I can copy-paste them directly onto my AdvancedApplicationDevelopment page?
     195
     196AI: Structured the requested code examples into the proper wiki markup format, ensuring the Java syntax highlighting blocks and explanatory documentation comments were clean and readable.