rebase and resubmit

Change-Id: I840888ad5aadceaacb5cd64c6472614cd82ffe17
diff --git a/src/main/java/cheat/CheatInterfnterface.java b/src/main/java/cheat/CheatInterfnterface.java
index 95ef6bb..cca8818 100644
--- a/src/main/java/cheat/CheatInterfnterface.java
+++ b/src/main/java/cheat/CheatInterfnterface.java
@@ -1,6 +1,7 @@
 package cheat;
 import org.apache.commons.lang3.tuple.Pair;
-import object.Appeal;
+
+import entity.Appeal;
 public interface CheatInterfnterface{
     public Pair<String,String>[] GetFeakSeed();//返回做假种的列表,<seedid,userid>
     public void DetectFeakSeed();//检测所有种子是否为假种,并将检测结果写入数据表
diff --git a/src/main/java/database/DataManagerInterface.java b/src/main/java/database/DataManagerInterface.java
index d284288..2304567 100644
--- a/src/main/java/database/DataManagerInterface.java
+++ b/src/main/java/database/DataManagerInterface.java
@@ -1,12 +1,12 @@
 package database;
 
-import object.BegInfo;
-import object.Notice;
-import object.Post;
-import object.Profile;
-import object.Seed;
-import object.User;
-import object.UserPT;
+import entity.BegInfo;
+import entity.Notice;
+import entity.Post;
+import entity.Profile;
+import entity.Seed;
+import entity.User;
+import entity.UserPT;
 public interface DataManagerInterface{
 //DB1
 
diff --git a/src/main/java/database/Database2.java b/src/main/java/database/Database2.java
index 79c55f9..8d919b6 100644
--- a/src/main/java/database/Database2.java
+++ b/src/main/java/database/Database2.java
@@ -12,19 +12,19 @@
 
 import com.querydsl.jpa.impl.JPAQuery;
 import com.querydsl.core.Tuple;
-import object.QBegInfo;
-import object.QUserVotes;
-import object.QSubmitSeed;
-import object.QProfile;
-import object.QSeed;
-import object.Seed;
-import object.User;
-import object.UserPT;
-import object.Notice;
-import object.BegInfo;
-import object.Post;
-import object.PostReply;
-import object.Profile;
+import entity.QBegInfo;
+import entity.QUserVotes;
+import entity.QSubmitSeed;
+import entity.QProfile;
+import entity.QSeed;
+import entity.Seed;
+import entity.User;
+import entity.UserPT;
+import entity.Notice;
+import entity.BegInfo;
+import entity.Post;
+import entity.PostReply;
+import entity.Profile;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/src/main/java/object/Appeal.java b/src/main/java/entity/Appeal.java
similarity index 98%
rename from src/main/java/object/Appeal.java
rename to src/main/java/entity/Appeal.java
index 5057179..36816c4 100644
--- a/src/main/java/object/Appeal.java
+++ b/src/main/java/entity/Appeal.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/src/main/java/object/BegInfo.java b/src/main/java/entity/BegInfo.java
similarity index 97%
rename from src/main/java/object/BegInfo.java
rename to src/main/java/entity/BegInfo.java
index 4c3589a..fe3174d 100644
--- a/src/main/java/object/BegInfo.java
+++ b/src/main/java/entity/BegInfo.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.util.Date;
 
diff --git a/src/main/java/object/Notice.java b/src/main/java/entity/Notice.java
similarity index 83%
rename from src/main/java/object/Notice.java
rename to src/main/java/entity/Notice.java
index a0b2b11..24ef954 100644
--- a/src/main/java/object/Notice.java
+++ b/src/main/java/entity/Notice.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -22,4 +22,8 @@
 
     @Column(name = "tag", length = 100)
     public String posttag;
+    
+    // 添加默认无参构造函数,JPA规范要求
+    public Notice() {
+    }
 }
diff --git a/src/main/java/object/Post.java b/src/main/java/entity/Post.java
similarity index 98%
rename from src/main/java/object/Post.java
rename to src/main/java/entity/Post.java
index 463e242..1593ca0 100644
--- a/src/main/java/object/Post.java
+++ b/src/main/java/entity/Post.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.util.Date;
 
diff --git a/src/main/java/object/PostReply.java b/src/main/java/entity/PostReply.java
similarity index 98%
rename from src/main/java/object/PostReply.java
rename to src/main/java/entity/PostReply.java
index bc95625..2845f10 100644
--- a/src/main/java/object/PostReply.java
+++ b/src/main/java/entity/PostReply.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.util.Date;
 import javax.persistence.*;
diff --git a/src/main/java/object/Profile.java b/src/main/java/entity/Profile.java
similarity index 98%
rename from src/main/java/object/Profile.java
rename to src/main/java/entity/Profile.java
index c8469a9..2ff6979 100644
--- a/src/main/java/object/Profile.java
+++ b/src/main/java/entity/Profile.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/src/main/java/object/Seed.java b/src/main/java/entity/Seed.java
similarity index 98%
rename from src/main/java/object/Seed.java
rename to src/main/java/entity/Seed.java
index b4f4c16..eabf49d 100644
--- a/src/main/java/object/Seed.java
+++ b/src/main/java/entity/Seed.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.util.Date;
 
diff --git a/src/main/java/entity/SubmitSeed.java b/src/main/java/entity/SubmitSeed.java
new file mode 100644
index 0000000..2cec77d
--- /dev/null
+++ b/src/main/java/entity/SubmitSeed.java
@@ -0,0 +1,34 @@
+package entity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "SubmitSeed")
+public class SubmitSeed {
+
+    @EmbeddedId
+    private SubmitSeedId id;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "beg_id", referencedColumnName = "beg_id", foreignKey = @ForeignKey(name = "fk_ss_beg"))
+    private BegInfo begInfo;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "seed_id", referencedColumnName = "seed_id", foreignKey = @ForeignKey(name = "fk_ss_seed"))
+    private Seed seed;
+
+    @Column(name = "votes", nullable = false)
+    private int votes;
+
+    public SubmitSeed() {}
+
+    public SubmitSeedId getId() {
+        return id;
+    }
+
+    public void setId(SubmitSeedId id) {
+        this.id = id;
+    }
+
+    // getters and setters for begInfo, seed, and votes
+}
diff --git a/src/main/java/entity/SubmitSeedId.java b/src/main/java/entity/SubmitSeedId.java
new file mode 100644
index 0000000..f071ac3
--- /dev/null
+++ b/src/main/java/entity/SubmitSeedId.java
@@ -0,0 +1,47 @@
+package entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class SubmitSeedId implements Serializable {
+    private String begId;
+    private String seedId;
+
+    public SubmitSeedId() {}
+
+    public SubmitSeedId(String begId, String seedId) {
+        this.begId = begId;
+        this.seedId = seedId;
+    }
+
+    // 重写 equals 和 hashCode 方法
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        SubmitSeedId that = (SubmitSeedId) o;
+        return begId.equals(that.begId) && seedId.equals(that.seedId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(begId, seedId);
+    }
+
+    // getters and setters
+    public String getBegId() {
+        return begId;
+    }
+
+    public void setBegId(String begId) {
+        this.begId = begId;
+    }
+
+    public String getSeedId() {
+        return seedId;
+    }
+
+    public void setSeedId(String seedId) {
+        this.seedId = seedId;
+    }
+}
diff --git a/src/main/java/object/TTorent.java b/src/main/java/entity/TTorent.java
similarity index 64%
rename from src/main/java/object/TTorent.java
rename to src/main/java/entity/TTorent.java
index be9051d..167e853 100644
--- a/src/main/java/object/TTorent.java
+++ b/src/main/java/entity/TTorent.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 public class TTorent{
     
diff --git a/src/main/java/object/TransRecord.java b/src/main/java/entity/TransRecord.java
similarity index 98%
rename from src/main/java/object/TransRecord.java
rename to src/main/java/entity/TransRecord.java
index 7f1c800..cf7ac7f 100644
--- a/src/main/java/object/TransRecord.java
+++ b/src/main/java/entity/TransRecord.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
diff --git a/src/main/java/object/TransportId.java b/src/main/java/entity/TransportId.java
similarity index 98%
rename from src/main/java/object/TransportId.java
rename to src/main/java/entity/TransportId.java
index 8e102d3..f79962f 100644
--- a/src/main/java/object/TransportId.java
+++ b/src/main/java/entity/TransportId.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.io.Serializable;
 import java.util.Objects;
diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java
new file mode 100644
index 0000000..603ec85
--- /dev/null
+++ b/src/main/java/entity/User.java
@@ -0,0 +1,57 @@
+package entity;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import com.querydsl.core.annotations.QueryEntity;
+
+@QueryEntity
+@Entity(name="User")
+@Table(name = "User")
+public class User {
+    @Id
+    @Column(name = "user_id", length = 36, nullable = false)
+    private String userid;
+
+    @Column(name = "email", nullable = false, length = 255, unique = true)
+    private String email;
+
+    @Column(name = "username", length = 100, nullable = false)
+    public String username;
+
+    @Column(name = "password", length = 255, nullable = false)
+    public String password;
+
+    @Column(name = "gender", nullable = false)
+    public String sex;
+
+    @Transient
+    public String age;
+
+    @Column(name = "school")
+    public String school;
+
+    @Column(name = "avatar_url")
+    public String pictureurl;
+
+    @Column(name = "bio")
+    public String profile;
+
+    @Column(name = "account_status", nullable = false)
+    public boolean accountstate;
+
+    @Column(name = "invite_left", nullable = false)
+    public int invitetimes;
+
+    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
+    public UserPT userPT;
+
+    // Constructors, getters, setters
+    public User() {}
+}
diff --git a/src/main/java/object/UserId.java b/src/main/java/entity/UserId.java
similarity index 97%
rename from src/main/java/object/UserId.java
rename to src/main/java/entity/UserId.java
index c68ce68..bc25675 100644
--- a/src/main/java/object/UserId.java
+++ b/src/main/java/entity/UserId.java
@@ -1,4 +1,4 @@
-package object;
+package entity;
 
 import java.io.Serializable;
 import java.util.Objects;
diff --git a/src/main/java/object/UserPT.java b/src/main/java/entity/UserPT.java
similarity index 72%
rename from src/main/java/object/UserPT.java
rename to src/main/java/entity/UserPT.java
index db3703f..bc5d455 100644
--- a/src/main/java/object/UserPT.java
+++ b/src/main/java/entity/UserPT.java
@@ -1,7 +1,9 @@
-package object;
+package entity;
 
+import javax.persistence.CascadeType;
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.ForeignKey;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
@@ -9,16 +11,19 @@
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 
-@Entity
+import com.querydsl.core.annotations.QueryEntity;
+
+@QueryEntity
+@Entity(name="UserPT")
 @Table(name = "UserPT")
 public class UserPT {
     @Id
     @Column(name = "user_id", length = 36, nullable = false)
     public String userid;
 
-    @OneToOne(optional = false)
+    @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
     @MapsId
-    @JoinColumn(name = "user_id", referencedColumnName = "user_id", foreignKey = @ForeignKey(name = "fk_pt_user"))
+    @JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "fk_pt_user"))
     public User user;
 
     @Column(name = "magic", nullable = false)
diff --git a/src/main/java/entity/UserVotes.java b/src/main/java/entity/UserVotes.java
new file mode 100644
index 0000000..af28e3c
--- /dev/null
+++ b/src/main/java/entity/UserVotes.java
@@ -0,0 +1,44 @@
+package entity;
+
+import java.util.Date;
+import javax.persistence.*;
+
+@Entity
+@Table(name = "UserVotes")
+public class UserVotes {
+
+    @EmbeddedId
+    private UserVotesId id;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "user_id", referencedColumnName = "user_id", 
+                foreignKey = @ForeignKey(name = "fk_user_votes_user"))
+    private User user;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "beg_id", referencedColumnName = "beg_id", 
+                foreignKey = @ForeignKey(name = "fk_user_votes_beg"))
+    private BegInfo begInfo;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "seed_id", referencedColumnName = "seed_id", 
+                foreignKey = @ForeignKey(name = "fk_user_votes_seed"))
+    private Seed seed;
+
+    @Column(name = "created_at", nullable = false)
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date createdAt;
+
+    public UserVotes() {}
+
+    // getter and setter for the composite key and other fields
+    public UserVotesId getId() {
+        return id;
+    }
+
+    public void setId(UserVotesId id) {
+        this.id = id;
+    }
+
+    // getters and setters for user, begInfo, seed, createdAt
+}
diff --git a/src/main/java/entity/UserVotesId.java b/src/main/java/entity/UserVotesId.java
new file mode 100644
index 0000000..4c0ce5f
--- /dev/null
+++ b/src/main/java/entity/UserVotesId.java
@@ -0,0 +1,57 @@
+package entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class UserVotesId implements Serializable {
+    private String userId;
+    private String begId;
+    private String seedId;
+
+    public UserVotesId() {}
+
+    public UserVotesId(String userId, String begId, String seedId) {
+        this.userId = userId;
+        this.begId = begId;
+        this.seedId = seedId;
+    }
+
+    // 重写 equals 和 hashCode 方法
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        UserVotesId that = (UserVotesId) o;
+        return userId.equals(that.userId) && begId.equals(that.begId) && seedId.equals(that.seedId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(userId, begId, seedId);
+    }
+
+    // getters and setters
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getBegId() {
+        return begId;
+    }
+
+    public void setBegId(String begId) {
+        this.begId = begId;
+    }
+
+    public String getSeedId() {
+        return seedId;
+    }
+
+    public void setSeedId(String seedId) {
+        this.seedId = seedId;
+    }
+}
diff --git a/src/main/java/entity/config.java b/src/main/java/entity/config.java
new file mode 100644
index 0000000..0cf39c1
--- /dev/null
+++ b/src/main/java/entity/config.java
@@ -0,0 +1,14 @@
+package entity;
+
+public class config {
+    public String TrackerURL;
+    public int FarmNumber;
+    public int FakeTime;
+    public int BegVote;
+    // 请根据实际环境修改为可达的地址
+    public String SqlURL = "192.168.5.9:3306";
+    public String Database = "pt_database";
+    public String TestDatabase = "pt_database_test";
+    public String SqlPassword = "123456";
+    public String SqlUsername = "root";
+}
diff --git a/src/main/java/object/SubmitSeed.java b/src/main/java/object/SubmitSeed.java
deleted file mode 100644
index 3b22811..0000000
--- a/src/main/java/object/SubmitSeed.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package object;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.ForeignKey;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-
-@Entity
-@Table(name = "SubmitSeed")
-public class SubmitSeed {
-    @Id
-    @Column(name = "beg_id", length = 64, nullable = false)
-    public String begId;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "beg_id", referencedColumnName = "beg_id", foreignKey = @ForeignKey(name = "fk_ss_beg"), insertable = false, updatable = false)
-    public BegInfo begInfo;
-
-    @Id
-    @Column(name = "seed_id", length = 64, nullable = false)
-    public String seedId;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "seed_id", referencedColumnName = "seed_id", foreignKey = @ForeignKey(name = "fk_ss_seed"), insertable = false, updatable = false)
-    public Seed seed;
-
-    @Column(name = "votes", nullable = false)
-    public int votes;
-}
\ No newline at end of file
diff --git a/src/main/java/object/User.java b/src/main/java/object/User.java
deleted file mode 100644
index 5e8dfaa..0000000
--- a/src/main/java/object/User.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package object;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "User", uniqueConstraints = @UniqueConstraint(name = "uniq_email", columnNames = {"email"}))
-@IdClass(UserId.class)
-public class User {
-    @Id
-    @Column(name = "user_id", length = 36, nullable = false)
-    public String userid;
-
-    @Column(name = "username", length = 100, nullable = false)
-    public String username;
-
-    @Column(name = "password", length = 255, nullable = false)
-    public String password;
-
-    @Column(name = "gender", nullable = false)
-    public String sex;
-
-    @Transient
-    public String age;
-
-    @Id
-    @Column(name = "email", length = 255, nullable = false)
-    public String email;
-
-    @Column(name = "school")
-    public String school;
-
-    @Column(name = "avatar_url")
-    public String pictureurl;
-
-    @Column(name = "bio")
-    public String profile;
-
-    @Column(name = "account_status", nullable = false)
-    public boolean accountstate;
-
-    @Column(name = "invite_left", nullable = false)
-    public int invitetimes;
-}
diff --git a/src/main/java/object/UserVotes.java b/src/main/java/object/UserVotes.java
deleted file mode 100644
index 813c292..0000000
--- a/src/main/java/object/UserVotes.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package object;
-
-import java.util.Date;
-import javax.persistence.*;
-
-@Entity
-@Table(name = "UserVotes")
-public class UserVotes {
-    @Id
-    @Column(name = "user_id", length = 36, nullable = false)
-    public String userId;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "user_id", referencedColumnName = "user_id", 
-                foreignKey = @ForeignKey(name = "fk_user_votes_user"), 
-                insertable = false, updatable = false)
-    public User user;
-
-    @Id
-    @Column(name = "beg_id", length = 64, nullable = false)
-    public String begId;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "beg_id", referencedColumnName = "beg_id", 
-                foreignKey = @ForeignKey(name = "fk_user_votes_beg"), 
-                insertable = false, updatable = false)
-    public BegInfo begInfo;
-
-    @Id
-    @Column(name = "seed_id", length = 64, nullable = false)
-    public String seedId;
-
-    @ManyToOne(optional = false)
-    @JoinColumn(name = "seed_id", referencedColumnName = "seed_id", 
-                foreignKey = @ForeignKey(name = "fk_user_votes_seed"), 
-                insertable = false, updatable = false)
-    public Seed seed;
-
-    @Column(name = "created_at", nullable = false)
-    @Temporal(TemporalType.TIMESTAMP)
-    public Date createdAt;
-}
diff --git a/src/main/java/object/config.java b/src/main/java/object/config.java
deleted file mode 100644
index a620518..0000000
--- a/src/main/java/object/config.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package object;
-
-public class config {
-    public String TrackerURL;
-    public int FarmNumber;
-    public int FakeTime;
-    public int BegVote;
-    public String SqlURL="192.168.5.9:3306";
-    public String Database="pt_database";
-    public String TestDatabase="pt_database_test";
-}
diff --git a/src/main/java/tracker/Tracker.java b/src/main/java/tracker/Tracker.java
index 8addf61..d53c258 100644
--- a/src/main/java/tracker/Tracker.java
+++ b/src/main/java/tracker/Tracker.java
@@ -1,19 +1,39 @@
 package tracker;
 
 import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.EntityTransaction;
 import javax.persistence.Persistence;
+
 import com.querydsl.jpa.impl.JPAUpdateClause;
-import object.QUserPT;
-import object.UserPT;
-import object.TTorent;
-import object.TransRecord;
+
+import entity.TTorent;
+import entity.TransRecord;
+import entity.config;
+import entity.QUserPT;
 
 public class Tracker implements TrackerInterface {
-    private static final EntityManagerFactory emf =
-        Persistence.createEntityManagerFactory("myPersistenceUnit");
+    private final EntityManagerFactory emf;
+
+    // 默认构造:产线数据库
+    public Tracker() {
+        config cfg = new config();
+        Map<String,Object> props = new HashMap<>();
+        props.put("javax.persistence.jdbc.url",
+                  "jdbc:mysql://" + cfg.SqlURL + "/" + cfg.Database);
+        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
+        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
+        this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+    }
+
+    // 测试传入:测试库
+    public Tracker(EntityManagerFactory emf) {
+        this.emf = emf;
+    }
 
     @Override
     public boolean AddUpLoad(String userid, int upload) {
@@ -27,38 +47,56 @@
                 .set(q.upload, q.upload.add(upload))
                 .execute();
             tx.commit();
-            return updated > 0;
+            // 成功时 updated>0 返回 false,失败时返回 true
+            return updated <= 0;
         } catch(Exception e) {
             if (tx.isActive()) tx.rollback();
-            return false;
+            return true;
         } finally {
             em.close();
         }
     }
 
     @Override
-    public boolean ReduceUpLoad(String userid,int upload){
-        return false;
-    };//给用户减上传量,返回0成功,返回1失败;
+    public boolean ReduceUpLoad(String userid, int upload){
+        EntityManager em = emf.createEntityManager();
+        EntityTransaction tx = em.getTransaction();
+        try {
+            tx.begin();
+            QUserPT q = QUserPT.userPT;
+            long updated = new JPAUpdateClause(em, q)
+                .where(q.userid.eq(userid))
+                .set(q.upload, q.upload.subtract(upload))
+                .execute();
+            tx.commit();
+            // 成功时 updated>0 返回 false,失败时返回 true
+            return updated <= 0;
+        } catch(Exception e) {
+            if (tx.isActive()) tx.rollback();
+            return true;
+        } finally {
+            em.close();
+        }
+    }
 
     @Override
     public boolean AddDownload(String userid,int download){
-        return false;
+        return true;
     };//给用户增加下载量,返回0成功,返回1失败;
 
     @Override
     public boolean ReduceDownload(String userid,int download){
-        return false;
+        return true;
     };//给用户减少下载量,返回0成功,返回1失败;
 
     @Override
     public boolean AddMagic(String userid,int magic){
-        return false;
+        return true;
     };//给用户增加魔力值,返回0成功,返回1失败;
 
     @Override
     public boolean ReduceMagic(String userid,int magic){
-        return false;
+        return true;
     };//给用户减少魔力值,返回0成功,返回1失败;
 
     @Override
diff --git a/src/main/java/tracker/TrackerInterface.java b/src/main/java/tracker/TrackerInterface.java
index 872d9ad..0c2df5c 100644
--- a/src/main/java/tracker/TrackerInterface.java
+++ b/src/main/java/tracker/TrackerInterface.java
@@ -1,8 +1,8 @@
 package tracker;
 import java.io.File;
 
-import object.TTorent;
-import object.TransRecord;
+import entity.TTorent;
+import entity.TransRecord;
 public interface TrackerInterface{
     public boolean AddUpLoad(String userid,int upload);//给用户新增上传量,返回0成功,返回1失败;
     public boolean ReduceUpLoad(String userid,int upload);//给用户减上传量,返回0成功,返回1失败;
diff --git a/src/main/java/vip/VipInterface.java b/src/main/java/vip/VipInterface.java
index 0ad764f..fd3413c 100644
--- a/src/main/java/vip/VipInterface.java
+++ b/src/main/java/vip/VipInterface.java
@@ -1,7 +1,9 @@
 package vip;
-import object.TTorent;
-import object.Seed;
 import org.apache.commons.lang3.tuple.Pair;
+
+import entity.Seed;
+import entity.TTorent;
+
 import java.io.File;
 public interface VipInterface{
     
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
index 3d68dc9..e40c753 100644
--- a/src/main/resources/META-INF/persistence.xml
+++ b/src/main/resources/META-INF/persistence.xml
@@ -8,21 +8,23 @@
         <!-- 指定 JPA 提供者 -->

         <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

 

-        <!-- 注册实体类 -->

+        <!-- 仅保留 UserPT 实体,避免其它实体的 @MapsId 映射错误 -->

+        <!-- 全限定名,确保 JPA 真正注册到 EMF -->

+        <class>object.UserPT</class>

         <class>object.Seed</class>

         <class>object.User</class>

-        <class>object.UserPT</class>

         <class>object.Notice</class>

         <class>object.BegInfo</class>

         <class>object.Post</class>

         <class>object.Profile</class>

+       

 

         <!-- 数据库连接配置 -->

         <properties>

             <property name="javax.persistence.jdbc.url" value="${DB_URL}"/>

             <property name="javax.persistence.jdbc.user" value="${DB_USER}"/>

             <property name="javax.persistence.jdbc.password" value="${DB_PASSWORD}"/>

-            <property name="javax.persistence.jdbc.driver" value="${DB_DRIVER}"/>

+            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>

 

             <!-- Hibernate 配置 -->

             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

diff --git a/src/test/java/trackertest/TrackerTest.java b/src/test/java/trackertest/TrackerTest.java
new file mode 100644
index 0000000..1ef5f44
--- /dev/null
+++ b/src/test/java/trackertest/TrackerTest.java
@@ -0,0 +1,119 @@
+package trackertest;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import entity.config;
+import tracker.Tracker;
+
+public class TrackerTest {
+    private static EntityManagerFactory emf;
+    private static EntityManager em;
+    private static List<String> userIds;
+    private static Map<String, Long> originalUploads;
+    private static Tracker tracker;
+
+    @BeforeAll
+    static void setup() throws Exception {
+        // 强制加载 MySQL 驱动,否则无法建立连接
+        Class.forName("com.mysql.cj.jdbc.Driver");
+        config cfg = new config();
+        Map<String,Object> props = new HashMap<>();
+        // 添加时区和 SSL 参数
+        String jdbcUrl = String.format(
+            "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
+            cfg.SqlURL, cfg.TestDatabase);
+        props.put("javax.persistence.jdbc.url", jdbcUrl);
+        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
+        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
+        props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
+        emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+        em = emf.createEntityManager();
+        // 使用简单实体名而非带包名前缀
+        userIds = em.createQuery(
+            "select u.userid from UserPT u", String.class
+        ).getResultList();
+
+        // 保存初始 upload 值
+        originalUploads = new HashMap<>();
+        for (String uid : userIds) {
+            Long up = em.createQuery(
+                "select u.upload from UserPT u where u.userid = :uid", Long.class
+            ).setParameter("uid", uid)
+             .getSingleResult();
+            originalUploads.put(uid, up != null ? up : 0L);
+        }
+        tracker = new Tracker(emf);
+    }
+
+    @AfterAll
+    static void teardown() {
+        if (em != null && em.isOpen()) em.close();
+        if (emf != null && emf.isOpen()) emf.close();
+    }
+
+    @TestFactory
+    Collection<DynamicTest> testAddUpLoad() {
+        Random rnd = new Random();
+        return userIds.stream()
+            .map(uid -> DynamicTest.dynamicTest("AddUpLoad for user " + uid, () -> {
+                int delta = rnd.nextInt(1000) + 1; // Ensure non-zero value
+                long before = originalUploads.get(uid);
+                
+                // 操作成功时返回 false
+                Assertions.assertFalse(tracker.AddUpLoad(uid, delta), 
+                    "AddUpLoad should return false on successful operation");
+                
+                // Clear the persistence context to ensure fresh data is fetched
+                em.clear();
+                
+                // Fetch updated value
+                Long after = em.createQuery(
+                    "select u.upload from UserPT u where u.userid = :uid", Long.class
+                ).setParameter("uid", uid)
+                 .getSingleResult();
+                
+                Assertions.assertEquals(before + delta, after, 
+                    "Upload value should be increased by " + delta);
+                
+                // 操作成功时返回 false
+                Assertions.assertFalse(tracker.ReduceUpLoad(uid, delta),
+                    "ReduceUpLoad should return false on successful operation");
+            }))
+            .collect(Collectors.toList());
+    }
+
+    @TestFactory
+    Collection<DynamicTest> testReduceUpLoad() {
+        Random rnd = new Random();
+        return userIds.stream()
+            .map(uid -> DynamicTest.dynamicTest("ReduceUpLoad for user " + uid, () -> {
+                long before = originalUploads.get(uid);
+                int max = (int)Math.min(before, 1000);
+                int delta = max > 0 ? rnd.nextInt(max) + 1 : 0;
+                if (delta == 0) return;  // 无可减量时跳过
+                Assertions.assertFalse(tracker.ReduceUpLoad(uid, delta));
+                Long after = em.createQuery(
+                    "select u.upload from UserPT u where u.userid = :uid", Long.class
+                ).setParameter("uid", uid)
+                 .getSingleResult();
+                Assertions.assertEquals(before - delta, after);
+                // 回滚到初始值
+                Assertions.assertFalse(tracker.AddUpLoad(uid, delta));
+            }))
+            .collect(Collectors.toList());
+    }
+}
diff --git a/src/test/java/trackertest/trackersystest.java b/src/test/java/trackertest/trackersystest.java
deleted file mode 100644
index 90ea14f..0000000
--- a/src/test/java/trackertest/trackersystest.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package trackertest;
-
-public class trackersystest {
-    
-}