I have probed numerous questions and documentation on this error and cannot seem to find where I am going wrong. The error is on this line:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails (`flutweets`.`refs`,
CONSTRAINT `refs_ibfk_1` FOREIGN KEY (`id`) REFERENCES `tweets` (`id`))
The database is MySQL, and I am using Workbench to inspect it; I also know that all the database engines are InnoDB and the Row Formats are Compact. I have three tables: tweets, hashtags, and references. Here is where I create the tables:
tweets Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + TWEETS_TABLE + "("
+ TWEETS_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ TWEETS_TIME + " VARCHAR(255),"
+ TWEETS_USER + " VARCHAR(255),"
+ TWEETS_TEXT + " VARCHAR(255) NOT NULL,"
+ TWEETS_LOCATION + " VARCHAR(255),"
+ TWEETS_CITY + " VARCHAR(255),"
+ TWEETS_PROVINCE + " VARCHAR(255),"
+ TWEETS_COUNTRY + " VARCHAR(255),"
+ TWEETS_TIME_ZONE + " VARCHAR(255),"
+ TWEETS_LATITUDE + " DECIMAL(20,16),"
+ TWEETS_LONGITUDE + " DECIMAL(20,16),"
+ "PRIMARY KEY (" + TWEETS_ID + ")"
+ ")");
. . .
hashtags Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + HASHTAG_TABLE + "("
+ HASHTAG_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ HASHTAG_TEXT + " VARCHAR(255),"
+ TWEETS_ID + " BIGINT NOT NULL,"
+ "PRIMARY KEY (" + HASHTAG_ID + "),"
+ "FOREIGN KEY (" + TWEETS_ID + ")"
+ "REFERENCES " + TWEETS_TABLE
+ "(" + TWEETS_ID + ")"
+ ")");
. . .
references Table
Statement stmt = null;
try {
stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE " + REF_TABLE + "("
+ REF_ID + " BIGINT NOT NULL AUTO_INCREMENT,"
+ REF_TEXT + " VARCHAR(255),"
+ TWEETS_ID + " BIGINT NOT NULL,"
+ "PRIMARY KEY (" + REF_ID + "),"
+ "FOREIGN KEY (" + TWEETS_ID + ")"
+ "REFERENCES " + TWEETS_TABLE
+ "(" + TWEETS_ID + ")"
+ ")");
Here are the statements I use to insert and the methods to insert them (I am using prepared statements):
/* INITIALIZE PREPARED STATEMENTS */
// Tweets
private static final String TWEETS_INSERT = "INSERT INTO " + TWEETS_TABLE
+ " (" + TWEETS_TIME + ", " + TWEETS_USER + ", " + TWEETS_TEXT + ", " + TWEETS_LOCATION + ", " + TWEETS_CITY + ", " + TWEETS_PROVINCE + ", "
+ TWEETS_COUNTRY + ", " + TWEETS_TIME_ZONE + ", " + TWEETS_LATITUDE + ", " + TWEETS_LONGITUDE + ")"
+ " VALUES(?,?,?,?,?,?,?,?,?,?)";
private PreparedStatement tweetsStatement;
// Hashtags
private static final String HASHTAGS_INSERT = "INSERT INTO " + HASHTAG_TABLE
+ " (" + HASHTAG_TEXT + ", " + TWEETS_ID + ")" + " VALUES(?,?)";
private PreparedStatement hashStatement;
// References
private static final String REF_INSERT = "INSERT INTO " + REF_TABLE
+ " (" + REF_TEXT + ", " + TWEETS_ID + ")" + " VALUES(?,?)";
private PreparedStatement refStatement;
public void insertHashtag(FluTweet tweet, int hashIndex, Integer tweetID) {
// Pull all of the Hashtag's relevant elements.
String hashText = tweet.getHashtag(hashIndex);
try {
hashStatement.setString(1, hashText);
hashStatement.setString(2, tweetID.toString());
//INSERT HASHTAG INTO TABLE
hashStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void insertReference(FluTweet tweet, int referenceIndex, Integer tweetID) {
// Pull all of the Reference's relevant elements.
String refText = tweet.getReference(referenceIndex);
try {
refStatement.setString(1, refText);
refStatement.setString(2, tweetID.toString());
//INSERT REFERENCE INTO TABLE
refStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
I have no idea why this is not working, any help would be much appreciated. Like I said, I have probed numerous other posts and cannot find relevant help.
Background
I found out the answer to my own question. It was never a problem with any of the actual database handling. It turns out, when I was passing the id to be used as the foreign id in hashtags and references, I was getting my id from a counter in the main class; where every new tweet had a number that went with each hashtag and reference for that tweet that would later be used as a foreign key. That foreign key would reference the primary key in the tweets table, which auto increments.
Here was the problem:
It turns out that MySQL is NOT zero-indexed when you auto-increment; where the first value is zero, then one, then two, etc. Instead, it starts at one. So when I tried to reference the primary key with the foreign key, the counter that started at zero for every tweet that I assigned (the foreign key) was being incorrectly matched to the auto incrementing tweet id in the tweets table (primary key).
Therefore, I was always off by one .
I hope this helps anyone that may have a similar issue.
如果未设置有效的子类对象主键值,则可以看到MySQLIntegrityConstraintViolationException。如果忽略子类对象的主键值,则基于hibernate pojo / hbm.xml文件一级缓存中设置的配置(会话)将其刷新到数据库中。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.